题干
给你二叉树的根节点 root
和一个表示目标和的整数 targetSum
。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum
。如果存在,返回 true
;否则,返回 false
。
叶子节点 是指没有子节点的节点。
思路
基本思路是递归是没问题的,自我感觉不管是递归函数参数返回值,还是递归结束条件,再到递归单次操作都是没太大问题的。
class Solution {
public:
void path_val(TreeNode* node, int pathval, unordered_set<int>& uoset){
if(node->left == nullptr && node->right == nullptr){
uoset.insert(pathval);
return;
}
if(node->left) path_val(node->left, pathval + node->left->val, uoset);
if(node->right) path_val(node->right, pathval + node->right->val, uoset);
return;
}
bool hasPathSum(TreeNode* root, int targetSum) {
unordered_set<int> uoset;
if(root == nullptr) return false;
path_val(root, root->val, uoset);
if(uoset.find(targetSum) == uoset.end()) return false;
return true;
}
};
但是出来的延迟就是很高,这还是优化一次之后的结果。我觉得问题很可能出在unordered_set上面,它的.find()函数我可不知道怎么实现的。
所以看了看代码随想录,瞄到了这句话,遂豁然开朗:
soga.
正解
class Solution {
public:
bool traversal(TreeNode* node, int residual){
bool result_left = false;
bool result_right = false;
bool result = false;
if(node->left == nullptr && node->right == nullptr && residual == 0) return true;
else if(node->left == nullptr && node->right == nullptr && residual != 0) return false;
else{
if(node->left) result_left = traversal(node->left, residual-node->left->val);
if(node->right) result_right = traversal(node->right, residual-node->right->val);
result = result_left || result_right;
}
return result;
}
bool hasPathSum(TreeNode* root, int targetSum) {
if(root == nullptr) return false;
return traversal(root, targetSum-root->val);
}
};
话说——
首先用布尔值做传递就蛮天才的感觉,再其次是逐层递减看叶子结点是不是刚好减到0也比较巧妙倒是。
没按照卡码说的回溯写,对这种写法自己比较熟悉吗?可能是吧。