![在这里插入图片描述](https://img-blog.csdnimg.cn/a6fd29f66bf5451398c02ee6061c6f4f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBATmVmdV9seWg=,size_20,color_FFFFFF,t_70,g_se,x_16)
https://www.nowcoder.com/practice/508378c0823c423baa723ce448cbfd0c
递归初始版
思路:
让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。如果到了叶子节点最后count == 0,说明找到了目标和;反之如果遍历到了叶子节点,count不为0,就是没找到。
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
bool dfs(TreeNode *root,int count){
//到了叶子节点,count=0返回true
if(!root->left&&!root->right&&count==0)
return true;
//到了叶子节点,count!=0返回false
if(!root->left&&!root->right)
return false;
if(root->left) {
count-=root->left->val;
//根据回溯返回的值确定判断该路径是否为结果
//如果回溯返回的是false,那么直接判断右子树
if(dfs(root->left,count)) return true;
count+=root->left->val;
}
if(root->right) {
count-=root->right->val;
if(dfs(root->right,count)) return true;
count+=root->right->val;
}
return false;
}
bool hasPathSum(TreeNode* root, int sum) {
// write code here
if(!root) return false;
return dfs(root,sum-root->val);
}
};
递归精简版
(1)
if(root->left) {
count-=root->left->val;
if(dfs(root->left,count)) return true;
count+=root->left->val;
}
count-=root->left->val;作为参数传递时,不需要手动回溯将count的值加回来,因为局部变量的值在函数调用后不会改变,所以简化为
if(root->left) {
if(dfs(root->left,count-root->left->val)) return true;
}
(2)
简化根据叶子节点进行判断当前分支的过程:
原来叶子结点返回true说明找到路径,所以if判断返回true;叶子结点返回false说明没有找到路径,count值回溯,同时进入右分支的判断
//到了叶子节点,count=0返回true
if(!root->left&&!root->right&&count==0)
return true;
//到了叶子节点,count!=0返回false
if(!root->left&&!root->right)
return false;
即如果左分支没有返回ture就判断右分支,那么可以用 || 连接两个判断语句
if(root->left) {
count-=root->left->val;
//根据回溯返回的值确定判断该路径是否为结果
//如果回溯返回的是false,那么直接判断右子树
if(dfs(root->left,count)) return true;
count+=root->left->val;
}
if(root->right) {
count-=root->right->val;
if(dfs(root->right,count)) return true;
count+=root->right->val;
}
简化为:
return hasPathSum(root->left,targetSum-root->val)||hasPathSum(root->right,targetSum-root->val);
完整代码:
/**
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
class Solution {
public:
/**
*
* @param root TreeNode类
* @param sum int整型
* @return bool布尔型
*/
bool hasPathSum(TreeNode* root, int sum) {
// write code here
if(!root) return false;
if(!root->left && !root->right && sum==root->val) return true;
return hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val);
}
};
迭代
要实现路径的输出要使用中序遍历,而递归能做的栈都能做,所以可以使用栈来模拟。
此时栈里一个元素不仅要记录该节点指针,还要记录从头结点到该节点的路径数值总和。可以用pair结构来存放这个栈里的元素。栈里的一个元素可以定义为:pair<treenode*, int>即pair<节点指针,到此节点的路径和>
只要栈不为空,拿出栈中第一个元素,判断是否为叶子结点,如果为叶子结点看此时的路径和是否为targetSum。再判断该节点有没有左右子树,先放右孩子再放左孩子,这样拿出来的顺序才是中左右。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
if(!root) return false;
stack <pair<TreeNode*,int>> s;
s.push(pair<TreeNode*, int>(root,root->val));
while(!s.empty()){
pair<TreeNode*,int> t = s.top();
s.pop();
if(!t.first->left&&!t.first->right && t.second==targetSum) return true;
if(t.first->right)
s.push(pair<TreeNode*, int>(t.first->right, t.second + t.first->right->val));
if(t.first->left)
s.push(pair<TreeNode*, int>(t.first->left, t.second + t.first->left->val));
}
return false;
}
};
113. 路径总和 II
https://leetcode-cn.com/problems/path-sum-ii/
在上题的基础上,返回记录满足条件的路径
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> path;
vector<vector<int>> res;
void dfs(TreeNode *root,int count){
if(!root->left && !root->right && count==0) {
res.push_back(path);
return ;
}
if(!root->left && !root->right) return ;
if(root->left){
path.push_back(root->left->val);
dfs(root->left,count-root->left->val);
path.pop_back();
}
if(root->right){
path.push_back(root->right->val);
dfs(root->right,count-root->right->val);
path.pop_back();
}
return;
}
vector<vector<int>> pathSum(TreeNode* root, int targetSum) {
path.clear();
res.clear();
if(!root) return res;
path.push_back(root->val);
dfs(root,targetSum-root->val);
return res;
}
};