题目地址:力扣
这道题思路比较简单,但是要注意的是,一定要找到叶子结点才能判断是否满足,因此一定要遍历完所有的叶子结点,那么很容易想到的就是DFS,因此可以采用递归的方法。
解法1:递归法
思路:每到一个节点就检查一下,是否叶子结点。若是,则检查目标值是否和当前的叶子结点值相等,相等则说明满足返回true。若不是叶子节点,就继续往下检查,下面的目标值应该是当前目标值减去当前节点值。左右子树中只要有一条满足就则返回true,所以用或运算符。
class Solution {
public:
bool check(TreeNode* root, int target)
{ // 如果访问到了空节点,自然不满足
if (root == nullptr)
return false;
// 如果当前节点的左右孩子都非空,说明已经到了叶子结点
// 返回当前节点是否等于目标值的判断结果
if (root->left == nullptr && root->right == nullptr)
return root->val == target;
// 若左右孩子至少有一个非空,就继续检查左右孩子,检查的目标值应该是
// 当前目标值减去当前节点值
return (check(root->left, target-root->val) ||
check(root->right, target-root->val));
}
bool hasPathSum(TreeNode* root, int targetSum) {
return check(root, targetSum);
}
};
解法2:迭代法
递归法的一个劣势就是会重复计算,因此采用迭代的方法,很容易想到BFS,因此采用BFS。可以用队列存下每一个节点及上一个节点的目标值,出队的时候进行检查,检查当前节点是否满足是叶子节点而且等于上一个节点的目标值。
class Solution {
public:
bool hasPathSum(TreeNode* root, int targetSum) {
// 两个队列用于存储节点和目标值
queue<TreeNode*> node_q;
queue<int> tar_q;
// 先把root节点和targetSum存进去
node_q.push(root), tar_q.push(targetSum);
// 只要队不同就循环
while (!node_q.empty())
{
// 分别存储队头的节点和目标值
TreeNode *curNode = node_q.front();
int curTarget = tar_q.front();
// 节点非空才进来,空就直接pop出去
if (curNode != nullptr)
{
// 若满足叶子结点且值等于目标值就返回true
if (curNode->left == nullptr &&
curNode->right == nullptr &&
curNode->val == curTarget)
return true;
// 否则把左孩子和右孩子都加入队列
else{
node_q.push(curNode->left);
tar_q.push(curTarget - curNode->val);
node_q.push(curNode->right);
tar_q.push(curTarget - curNode->val);
}
}
node_q.pop();
tar_q.pop();
}
return false;
}
};
Accepted
- 117/117 cases passed (12 ms)
- Your runtime beats 46.31 % of cpp submissions
- Your memory usage beats 5.12 % of cpp submissions (21.3 MB)