LeetCode 437. Path Sum III

方法一:Brute Force

对于每个节点,计算以该节点为root时所有可能的个数。

Space: O(h), O(logn)~O(n)

Time: calpath O(n), 对于dfs, T(n) = 2T(n/2)+O(n)  所以总的时间复杂度O(nlogn),当然这是在balanced tree情况下,最坏O(n^2),因此 O(nlogn)~O(n^2)

class Solution {
public:
    int cnt=0;
    int pathSum(TreeNode* root, int sum) {
        dfs(root,sum);
        return cnt;
    }
    
    void dfs(TreeNode *root, int sum){
        if (root==NULL) return;
        calpath(root,sum);
        dfs(root->left,sum);
        dfs(root->right,sum);
    }
    
    void calpath(TreeNode *root, int sum){
        if (root==NULL) return;
        if (sum==root->val) ++cnt;
        calpath(root->left,sum-root->val);
        calpath(root->right,sum-root->val);
    }
};

 

也可以 return 可行的个数,这样可以更加精简,本质一样

/**
 * 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 cnt=0;
    int pathSum(TreeNode* root, int sum) {
        if (root==NULL) return 0;
        return calpath(root,sum) + pathSum(root->left,sum) + pathSum(root->right,sum);
    }
    
    int calpath(TreeNode *root, int sum){
        if (root==NULL) return 0;
        return (sum==root->val?1:0) + calpath(root->left,sum-root->val) + calpath(root->right,sum-root->val);
    }
};

 

方法二:PreSum (Memoization of Path Sum)

第一种方法有大量的节点重复计算。其实我们可以计算到当前节点的路径和,并把数量保存下来。分析可以详见:

https://leetcode.com/problems/path-sum-iii/discuss/141424/Python-step-by-step-walk-through.-Easy-to-understand.-Two-solutions-comparison.-:-)

特别需要注意,hashtable保存的路径和,一定是能延伸到当前节点的。所以函数最后 --count[curSum] 是必须加的,当递归返回上一层时,包含当前节点的路径 curSum 就不复存在了。

/**
 * 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> count; // <curSum, num>
        count.insert({0,1});
        return dfs(root,0,sum,count);
    }
    
    int dfs(TreeNode *root, int curSum, int target, unordered_map<int,int> &count){
        if (root==NULL) return 0;
        curSum += root->val;
        int res=count[curSum-target];
        ++count[curSum];
        
        res += dfs(root->left,curSum,target,count) + dfs(root->right,curSum,target,count);
        
        //when move to a different branch, the currPathSum is no longer available, hence remove one. 
        --count[curSum]; 
        return res;
    }
    
    
    
};

 

posted @ 2018-08-31 02:06  約束の空  阅读(155)  评论(0编辑  收藏  举报