今日份的打卡题目是lc112.路径总和。关于二叉树的题目。
112、113、437、129的解题思路本质上一样,在于个别细节的不同。对于二叉树而言,逃不掉的就是递归,而其中用的最多的方法就是DFS。我理解DFS是按照“走迷宫”的思路去理解,因为在走迷宫的时候,也是穷尽所有的可能性。
以下是关于四道题目的代码,代码附有解释。
leetcode112、路径总和
方法一:DFS
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
return dfs(root,0,sum);
}
bool dfs(TreeNode* root,int cursum,int sum){
//走到底了,还没有得到结果,直接返回
if(root==nullptr) return false;
//没有走到底,则对当前节点的值进行处理,可加可减
//减的话,不需要cursum这个参数,直接每次对sum进行减操作,并判断叶子节点时的sum是否等于0
cursum+=root->val;
//对当前节点处理完后,判断当前节点是不是叶子节点且满足条件
if(root->left==nullptr&&root->right==nullptr&&cursum==sum){
return true;
}
else{
return dfs(root->left,cursum,sum)||dfs(root->right,cursum,sum);
}
}
};
方法二:DFS+回溯
class Solution {
private:
bool flag=false;
int cursum=0;//全局变量,需要进行状态重置,以便下一个选择时使用的状态是没有改变的
public:
bool hasPathSum(TreeNode* root, int sum) {
dfs(root,sum);
return flag;
}
void dfs(TreeNode* root,int sum){
if(root==nullptr) return;//到底仍未符合条件,直接返回
cursum+=root->val;//加上当前节点的值
if(root->left==nullptr&&root->right==nullptr&&cursum==sum){
flag=1;
return;
}
dfs(root->left,sum);//当前节点的左孩子
dfs(root->right,sum);//当前节点的右孩子
cursum-=root->val;回溯,状态重置
}
};
leetcode113、路径总和Ⅱ
方法:DFS+回溯
class Solution {
private:
vector<vector<int>> ans;
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<int> temp;
dfs(root,sum,temp);
return ans;
}
void dfs(TreeNode* root,int sum,vector<int>& temp){
if(root==nullptr){
return;
}
temp.push_back(root->val);
sum-=root->val;
if(root->left==nullptr&&root->right==nullptr&&sum==0){
ans.push_back(temp);
temp.pop_back();//回溯,状态重置
return;
}
dfs(root->left,sum,temp);
dfs(root->right,sum,temp);
temp.pop_back();//回溯,状态重置
}
};
leetcode437、路径总和Ⅲ
方法:和leetcode112的DFS方法一致,只是需要进行递归嵌套
class Solution {
private:
int path=0;
public:
int pathSum(TreeNode* root, int sum) {
traverse(root,sum);
return path;
}
//遍历所有节点
void traverse(TreeNode* root,int sum){
if(root==nullptr) return;
dfs(root,sum);
if(root->left) traverse(root->left,sum);
if(root->right) traverse(root->right,sum);
}
//以该节点为出发点找到符合条件的路径
void dfs(TreeNode* root,int sum){
if(root==nullptr) return;
sum-=root->val;
if(sum==0){
path++;
}
dfs(root->left,sum);
dfs(root->right,sum);
}
};
leetcode129、求根到叶子节点数字之和
方法:参考leetcode112,DFS解法,完全一致
class Solution {
private:
int sum=0;
public:
int sumNumbers(TreeNode* root) {
dfs(root,0);
return sum;
}
void dfs(TreeNode* root,int num){
if(root==nullptr) return;
num=num*10+(root->val);//对当前节点的处理方式不同
if(root->left==nullptr&&root->right==nullptr){
sum+=num;
return;
}
dfs(root->left,num);
dfs(root->right,num);
}
};