LeetCode 112:路径总和
题目描述
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
【示例】
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
解题
递归
【思路】
如果存在一个根节点到叶节点的路径满足所有节点值和等于目标(用sum表示)的话,那么必然存在从根节点的左右子节点到叶节点的某一个路径,满足路径上所有节点值的和等于sum-root->val,其中root代表根节点。以此类推,若存在满足要求的路径,以那么该路径上任何一个节点为分界点,该节点之后到叶节点之后等于sum减去根节点到当前节点值的和。
上述描述会比较拗口,其本质思路是如果某一路径满足要求,那么沿着该路径遍历过程中,sum减去沿途节点值,到达叶节点时,sum为0。这个过程把求和转变为累减。逻辑如下:
- 遍历每个从根节点到叶节点的路径
- 沿途做减法,若到达叶节点时,sum恰好为0,则返回true;否则遍历下一条路径。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root==NULL)
return false;
if (root->left == NULL && root->right==NULL)
return root->val==sum;
return(hasPathSum(root->left, sum-root->val) || hasPathSum(root->right, sum-root->val));
}
};
迭代
【思路】
我们可以改变遍历方式,递归方法是深度优先的(DFS),那同样可以广度优先(BFS):逐层遍历二叉树,同时计算到达这一层每个节点时对应的总和,如果这一层中存在一个叶节点且其和恰好为目标值,则返回true;否则继续向下层序遍历。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if (root==NULL)
return false;
queue<TreeNode *> nodes;
queue<int> sums;
nodes.push(root);
sums.push(root->val);
while (!nodes.empty()){
int nums = nodes.size();
for (int i=0; i<nums; ++i){
root = nodes.front();
int cur_sum = sums.front();
if (root->left == NULL && root->right==NULL){
if (cur_sum==sum)
return true;
}
if (root->left){
nodes.push(root->left);
sums.push(cur_sum + root->left->val);
}
if (root->right){
nodes.push(root->right);
sums.push(cur_sum + root->right->val);
}
sums.pop();
nodes.pop();
}
}
return false;
}
};