Path Sum III
原题链接Path Sum III
给定一个二叉树,计算二叉树中有多少条路径的元素和等于某个值,路径只需要连续即可,不要求必须从根节点出发到达叶子节点
如果只是简单的递归,那么会很难求解,原因是在向下递归时需要考虑多种可能性,即
- 算上当前的元素值,继续向下递归,保持路径的连续性
- 不算当前的元素值,那么路径就会中断,需要重新以最初值开始遍历
其实如果是序列的话用动态规划应该不会差,但是这是二叉树诶。根据题意可知要找的是一条连续路径,那么纵观全局,这一条连续路径属于从根节点到叶子节点的路径的一部分,那么就可以用路径截取的方式
以示例中 10−>5−>3−>3 这条路径为例,其中10是根节点,最后一个3是叶子节点
而满足条件的路径是 5−>3 这一条,所以可以只看到 10−>5−>3 这条路径(在递归的过程中没到达一个节点就是一条从根节点到当前节点的路径)。而在这之前,递归的过程肯定也可以看到10这条路径(即刚从根节点出发),那么这两条路径作差,即 (10−>5−>3)−(10) 就变为 5−>3 这条路径,而且这条路径的和就是要求的sum
所以,只需要记录从根节点到当前节点这个递归过程中所有遇到的路径和,然后用到达当前节点时的路径和与给定的sum作差,判断差值是否出现在上述的路径和中即可
代码如下
/**
* 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:
int pathSum(TreeNode* root, int sum) {
unordered_map<int, int> hash;
//必要的,当没有到达根节点时,路径和为0(解决所求路径和从根节点开始的情况)
hash[0] = 1;
int count = 0;
findPathSum(root, sum, 0, hash, count);
return count;
}
private:
void findPathSum(TreeNode* root, int sum, int curSum, unordered_map<int, int>& hash, int& count)
{
if(!root) return;
/* 增加当前值 */
curSum += root->val;
/* 判断是否有一条子路径路径和为curSum - sum */
if(hash.find(curSum - sum) != hash.end())
count += hash[curSum - sum];
/* 这里需要先++再--,因为从当前节点返回后,这个节点后面的路径和都需要删掉 */
++hash[curSum];
findPathSum(root->left, sum, curSum, hash, count);
findPathSum(root->right, sum, curSum, hash, count);
--hash[curSum];
}
};
本题主要需要弄清楚如果找到要求的路径和,不能盲目递归