路径之和
描述
给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。
说明: 叶子节点是指没有子节点的节点。
示例:
给定如下二叉树,以及目标和 sum = 22,
5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1
返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。
思路和代码
递归:
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(root == NULL)
return false;
if(root->left == NULL && root->right == NULL)
return sum == root->val;
return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};
路径之和2
描述
不同于上一题,上一题只要返回有无等于sum的路径,而本题返回的是所有等于sum的路径。
思路和代码
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
vector<int> temp;
pathSum(root, sum, res, temp);
return res;
}
void pathSum(TreeNode* root, int sum, vector<vector<int>>& res, vector<int>& temp)
{
if(root == NULL)
return ;
temp.push_back(root->val);
if(root->left == NULL && root->right == NULL)
{
if(sum == root->val)
res.push_back(temp);
}
//递归左子树
pathSum(root->left, sum-root->val, res, temp);
//递归右子树
pathSum(root->right, sum-root->val, res, temp);
//回溯
temp.pop_back();
}
};
二叉树的最大路径和
描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
思路和代码
可以利用“最大连续子序列和”问题的思路。
如果说 Array 只有一个方向的话, 那么 BinaryTree 其实只是左、右两个方向而已,我们需要比较两个方向上的值。 不过,Array 可以从头到尾遍历,那么 BinaryTree 怎么办呢,我们可以采用 BinaryTree 最常用 的dfs来进行遍历。
先算出左右子树的结果L和R,如果L大于0,那么对后续结果是有利的,我们 加上 L,如果 R 大于 0,对后续结果也是有利的,继续加上 R。
注意,最后返回的是左子树和右子树较大值加上root->val返回给父节点,因为路径如果是L->root->R,那么就不会经过父节点,反之如果经过根节点,那么返回的应该是左孩子的左子树或右子树。
class Solution {
private:
int max_sum;
int dfs(TreeNode* root)
{
if(root == NULL)
return 0;
int l = dfs(root->left);
int r = dfs(root->right);
int sum = root->val;
if(l > 0)
sum += l;
if(r > 0)
sum += r;
max_sum = max(max_sum, sum);
return max(l, r) > 0 ? max(l, r) + root->val : root->val;
}
public:
int maxPathSum(TreeNode* root) {
max_sum = INT_MIN;
dfs(root);
return max_sum;
}
};