437. Path Sum III

DFS - brute force

ๆŠŠๆ‰€ๆœ‰ๅญๆจน้ƒฝ่จˆ็ฎ—ไธ€ๆฌก, ๆ‰€ไปฅ่ท‘ ไปฅๆ น็‚บ่ตท้ปž็š„ๆจน ๏ผ‹ ไปฅๅทฆๅญๆจนๆ น็‚บ่ตท้ปž็š„ๆจน ๏ผ‹ ไปฅๅณๅญๆจนๆ น็‚บ่ตท้ปž็š„ๆจน

ๅ› ็‚บ้€™ๆจฃๅฐฑ่ฎŠๆˆๅตŒๅฅ—็š„่ตฐ่จช

ๆ‰€ไปฅ time : ๆœ€ๅทฎ O(n^2), BST: O(nlogn)

space: O(n)

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int pathSum(TreeNode root, int targetSum) {
        // DFS all the sub trees, and cal them all
        if (root == null) return 0;
        
        // ๆณจๆ„, ็ฌฌไธ€ๅ€‹ root ๅŽปๅซ helper, ๅฆๅ…ฉๅ€‹ๆ˜ฏๅตŒๅฅ—, ๅˆๅ‘ผๅซไบ†ๆœฌ่บซ
        // ๆ‰€ไปฅๆœƒไธๆ–ทๅœฐๅตŒๅฅ—... 
        return helper(root, targetSum) + 
            pathSum(root.left, targetSum) + 
            pathSum(root.right, targetSum); 
    }
    
     private int helper(TreeNode node, int sum) {
        if (node == null) return 0;
         // ไธ็”จroot to leaf, ๆ‰€ไปฅไธ็”จ root.left == null && root.right == null ็š„ๆขไปถ
        return (node.val == sum ? 1 : 0) 
            + helper(node.left, sum - node.val) + helper(node.right, sum - node.val);
    }
}
class Solution {
    public int pathSum(TreeNode root, int targetSum) {
        if (root == null) {
            return 0;
        }
        return dfs(root, targetSum) + 
            pathSum(root.left, targetSum) + 
            pathSum(root.right, targetSum);
    }
    private int dfs(TreeNode root, int sum) {
        if (root == null) {
            return 0;
        }
        int leftCount = dfs(root.left, sum - root.val);
        int rightCount = dfs(root.right, sum - root.val);
        return (sum == root.val ? 1 : 0) + leftCount + rightCount;
    }
}

2. HashMap(presum, path count) + backtracking

ๅฆ‚ไฝ•ไธ่ตฐ่จชๆ‰€ๆœ‰็š„ subtree?

use memories ็š„ๆŠ€ๅทง,

ไปฅ 10, 5, 3 ้€™ไพ‹ๅญ, ่ตฐ่จชๆ™‚่จˆ็ฎ— presum & path count

(10,1), (15,1), 18 ่ตฐๅˆฐ 18

(18 - target(8)) = 10 exists in map , ไปฃ่กจๆœ‰่ทฏๅพ‘็ฌฆๅˆๆˆ‘ๅ€‘็š„ targetSum

so path count = map.get(10)'; map's count record how many path sum count we have

then recursive do node.left & node.right

ๆ‰€ไปฅๅฐฑๅ‡่จญไปฅ็›ฎๅ‰็š„ sum, ๅŽป่ตฐๅทฆๅณ, ๆ‰€ไปฅๅ…ˆ map sum, count+1

map.put(sum, map.getOrDefault(sum, 0)+1);

dfs(root.left, targetSum, map, sum);
dfs(root.right, targetSum, map, sum);

ๆœ€ๅพŒๅœจ backtracking ๅ›žไพ†

at last, need to do a backtracking, remove the last count

map.put(curSum, map.get(curSum) - 1);

idea like subarray sum equals k, just this one is tree style

time: O(n)

space: O(n)

class Solution {
    // use hash map to store map(presum, count)
    // presum, if map.get(presum - target) exists, retirive the count(it's the correct path)
    public int pathSum(TreeNode root, int targetSum) {
        if (root == null) return 0;
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, 1); // zero sum, ไนŸๆ˜ฏไธ€ๅ€‹ count, ่ตท้ปž, ่ฆๆณจๆ„, ไธ็„ถๆœ‰ไบ›ใ€‚case ๆœƒๆœ‰ๅ•้กŒ 
        return helper(root, 0, targetSum, map);
    }
    private int helper(TreeNode node, int curSum, int targetSum, Map<Integer, Integer> map) {
        if (node == null) return 0;

        curSum += node.val;
        int count = map.getOrDefault(curSum - targetSum, 0);
        
        map.put(curSum, map.getOrDefault(curSum, 0) + 1); // try backtracking
        
        count += helper(node.left, curSum, targetSum, map);
        count += helper(node.right, curSum, targetSum, map);
        
        map.put(curSum, map.get(curSum) - 1); // do backtracking
        return count;
    }
}

global variable

class Solution {
    int count = 0;
    public int pathSum(TreeNode root, int targetSum) {
        
        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);
        dfs(root, targetSum, map, 0);
        return count;
    }

    private void dfs(TreeNode root, int targetSum, Map<Integer, Integer> map, int sum) {
        if (root == null) {
            return;
        }
        sum += root.val; // but why use same sum work? becase dfs will go back to upper level
        count += map.getOrDefault(sum - targetSum, 0);
        
        map.put(sum, map.getOrDefault(sum, 0)+1);
        
        dfs(root.left, targetSum, map, sum);
        dfs(root.right, targetSum, map, sum);
        
        map.put(sum, map.get(sum) -1); // notice map backtracking
    }
}

/*

find num of path sum equal to targetSum

map(sum, count)

ex:
Input: root = [10,5,-3,3,2,null,11,3,-2,null,1], targetSum = 8
Output: 3

map(10, 1)
18 - 8 find in map => count += map(10, 1)

ex:
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
Output: 3

       5,
   4,      8,
 11,null,        13,4,
7,2, null,null, 5,1


0,1
5,1

5 4 11 2 = 22 find in (0,1)

27 -22 = 5 find in (5,1)
27 -22 = 5 find in (5,1)

*/

dfs sum can show all the sum in a tree

private void dfs(TreeNode root, int targetSum, Map<Integer, Integer> map, int sum) {
        if (root == null) {
            return;
        }
        sum += root.val; // but why use same sum work? becase dfs will go back to upper level
        System.out.println(sum);

Last updated