Leetcode112:路经总和
题目要求:给你二叉树的根节点 root 和一个表示目标和的整数 targetSum ,判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。
叶子节点 是指没有子节点的节点。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-sum
1.深度优先(dfs)/递归
->一道比较简单的题目,一看就知道可以使用递归的方式解决。
以往的dfs是返回所有路径,这题只需要判断是否存在一条路符合条件,因此简化了问题。注意到递归问题所有的结果都 return 自最底部的判断,因此在这里bfs或者递归形式上可以理解为对每个树节点赋值 true 或者 false; 当递归到最底部左侧某条路,如果这条路符合条件 返回 true,表示对这个节点的肯定。 他的右边条件已经无所谓了,或者说当递归到最底部左侧某条路,如果这条路不符合条件 返回 false,但他上一节点往右子树遍历返回true,那么这个节点我们还是肯定的,给true。因此这题只需要判断是否存在这样的路。 所以 return的应该是个或运算。这样的方式也就是说只要遍历到一个终点返回true, 在不断递归到最上面一层时肯定是返回true的。就算遍历到一个点不符合条件false,只要存在true就能翻盘。因为递归的问题,每一层是一样的,返回值永远是被最后一层决定,left和right判断的是当前节点的子节点传来的消息,是否找到了这样的路径~
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
//递归的方式,深度优先遍历回溯
if(!root)
return false;
if(!root->left && !root->right)
return targetSum==root->val;
bool left=hasPathSum(root->left, targetSum-root->val);
bool right=hasPathSum(root->right, targetSum-root->val);
return left||right;
}
};
下面贴一个失败的程序:
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
//递归的方式,深度优先遍历回溯
if(!root)
return false;
if(!root->left && !root->right)
return targetSum==root->val;
if(root->left!=nullptr) //~~~~~~~~增加的判断!!!
bool left=hasPathSum(root->left, targetSum-root->val);
if(root->right!=nullptr) //~~~~~~~~增加的判断!!!
bool right=hasPathSum(root->right, targetSum-root->val);
return left||right;
}
};
这个程序和上面成功的程序相比多了对每个结点的判断,非空才进入,程序会报错。这是由于假设某个结点左子树是空,但是右子树非空在最后返回的时候 left没有赋值,return左或右会出现问题! 所以不用判断是否空,转而和第一个程序一个,先进入,再判断是否是空,如果是空 返回false:
if(!root)
return false;
这个的意思就是当前节点的左子树没有机会获得可行解了,因为当前结点在进入程序时已经判断了是不是叶子结点,已经不是叶子结点的情况下左侧丧失希望,只能依赖右侧了。
2.广度优先(dfs)/递归
->注意到从根节点到达每一个节点的路径是唯一的!这意味着在某个节点,从根节点到该节点的数字累加和是固定的。因此我们可以在遍历每个节点加入队列的同时计算到当前位置的累加值,在Bfs平铺搜索到最后一层时,如果累加值符合条件返回 true。 如果不符合条件 continue 就略过这个点的节点扩张!退出while循环时候还没有返回 true 就返回false
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
//试试bfs
queue<pair<TreeNode*,int>>que;
if(!root)
return false;
que.emplace(root,root->val);
while(!que.empty()){
TreeNode* node=que.front().first;
int temp=que.front().second;
que.pop();
if(!node->left && !node->right){
if(temp==targetSum)
return true;
}
if(node->left!=nullptr)
que.emplace(node->left,temp+node->left->val);
if(node->right!=nullptr)
que.emplace(node->right,temp+node->right->val);
}
return false;
}
};