1. 程式人生 > >437. Path Sum III(python+cpp)

437. Path Sum III(python+cpp)

題目:

You are given a binary tree in which each node contains an integer value. Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. Example:

root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8

      10
     /  \
    5   -3    
   / \    \   
  3   2   11  
 / \   \ 
3  -2   1

Return 3. The paths that sum to 8 are:
1.  5 -> 3
2.  5 -> 2 -> 1
3. -3 -> 11

解釋: 返回二叉樹中路徑和為sum的路徑的個數,需要注意的是路徑無需從root開始以leaf結束,也是經典的dfs問題。其實也不需要把path記錄下來,因為是求路徑和,所以只需要把路徑和傳入即可。 遞迴的寫法,內層函式呼叫需要遞迴,外層函式呼叫還需要遞迴,會重複計算,速度特別慢,是暴力的無記憶遞迴解法:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
def dfs(root,sum): res=0 if root==None: return res if root.val==sum: res+=1 if root.left: res+=dfs(root.left,sum-root.val) if root.right: res+=dfs(root.right,sum-root.val) return res if root==None: return 0 left,right=0,0 if root.left: left=self.pathSum(root.left,sum) if root.right: right=self.pathSum(root.right,sum) return dfs(root,sum)+left+right

記憶化,用一個字典記錄,真是牛逼了…

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
from collections import defaultdict
class Solution:
    def pathSum(self, root, sum):
        """
        :type root: TreeNode
        :type sum: int
        :rtype: int
        """
        self.result=0
        curSum=defaultdict(int)
        curSum[0]=1
        def helper(curSum,root,curVal,target):
            if not root:
                return
            #curValue表示從root到當前結點的路徑的和
            curVal+=root.val
            self.result+=curSum[curVal-target]
            curSum[curVal]+=1
            if root.left:
                helper(curSum,root.left,curVal,target)
            if root.right:
                helper(curSum,root.right,curVal,target)
            curSum[curVal]-=1
        if root:
            helper(curSum,root,0,sum)
        return self.result

c++程式碼:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
#include <map>
using namespace std;
class Solution {
    int result;
public:
    int pathSum(TreeNode* root, int sum) {
        map<int,int>curSum;
        curSum[0]=1;
        if (root)
            helper(root,curSum,0,sum);
        return result;
    }
    void helper(TreeNode*root ,map<int,int>& curSum,int curVal,int target)
    {
        if (!root)
            return ;
        curVal+=root->val;
        result+=curSum[curVal-target];
        curSum[curVal]++;
        if (root->left)
            helper(root->left,curSum,curVal,target);
        if(root->right)
            helper(root->right,curSum,curVal,target);
        curSum[curVal]--;
        
    }
};

總結: 在dfs的時候使用記憶化可以避免重複計算加快速度,多重dfs簡直是人間災難。