*lintcode246- Binary Tree Path Sum II- easy

Your are given a binary tree in which each node contains a value. Design an algorithm to get all paths which sum to a given value. The path does not need to start or end at the root or a leaf, but it must go in a straight line down.

Example

Given a binary tree:

    1
   / 
  2   3
 /   /
4   2

for target = 6, return

[
  [2, 4],
  [1, 3, 2]
]

1.加减试错递归法。递归定义是从传入的节点出发,把这个点加进备选名单弄出新的链条看看,向根走,试试一路上有没有可能使得sum == target的点。有的话,把这条路加到result里。并且在有这个节点的基础上,再递归看看从该节点的左节点出发走会怎么样,递归看看从该节点的右节点出发走会怎么样。最后删去该节点,避免影响。(前面同时递归了左右节点,不能让左节点保留着影响右节点试走路径)。这种做法主要因为用ArrayList作为buffer试错可以减少空间复杂度。辅助函数头:

private void helper(TreeNode current, int target, int level, List<Integer> buffer, List<List<Integer>> result)

2. 自己一开始做法:遍历嵌套递归。外面遍历每个节点。在每个节点上递归返回所有从这个点出发,随便结束在哪个点但sum == target的。虽然输出正确,但因为嵌套,最后会内存超时的。


1.加减试错递归法

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */


public class Solution {
    /*
     * @param root: the root of binary tree
     * @param target: An integer
     * @return: all valid paths
     */
    public List<List<Integer>> binaryTreePathSum2(TreeNode root, int target) {
        // write your code here
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        List<Integer> buffer = new ArrayList<Integer>();
        helper(root, target, 0, buffer, result);
        return result;
    }
    
    private void helper(TreeNode root, int target, int level, List<Integer> buffer, List<List<Integer>> result) {
        if (root == null) {
            return;
        }
        
        buffer.add(root.val);
        
        int sum = 0;
        for (int i = level; i >= 0; i--) {
            sum += buffer.get(i);
            if (sum == target) {
                List<Integer> list = new ArrayList<Integer>();
                for (int j = i; j <= level; j++) {
                    list.add(buffer.get(j));
                }
                result.add(list);
            }
        }
        
        helper(root.left, target, level + 1, buffer, result);
        helper(root.right, target, level + 1, buffer, result);
        
        // 是size还是length
        buffer.remove(buffer.size() - 1);
    }
}

2.遍历嵌套递归

/**
 * Definition of TreeNode:
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left, right;
 *     public TreeNode(int val) {
 *         this.val = val;
 *         this.left = this.right = null;
 *     }
 * }
 */


public class Solution {
    /*
     * @param root: the root of binary tree
     * @param target: An integer
     * @return: all valid paths
     */
    
    //???
    //感觉复杂度有点高,相当于遍历一次,每个点做一次递归。可行吗?
    public List<List<Integer>> binaryTreePathSum2(TreeNode root, int target) {
        // write your code here
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        Stack<TreeNode> stack = new Stack<TreeNode>();
        
        if (root == null) {
            return result;
        }
        
        stack.push(root);
        while (!stack.isEmpty()) {
            TreeNode crt = stack.pop();
            List<List<Integer>> paths = helper(crt, target);
            result.addAll(paths);
            if (crt.right != null) {
                stack.push(crt.right);
            }
            if (crt.left != null) {
                stack.push(crt.left);
            }
        }
        
        return result;
        
    }
    
    //从该点出发到根部路上所有满足加和为target的路径。
    private List<List<Integer>> helper(TreeNode root, int target) {
        
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        
        if (root == null) {
            return result;
        }
        
        if (root.val == target) {
            List<Integer> newPath = new ArrayList<Integer>();
            newPath.add(root.val);
            result.add(newPath);
        }
        
        List<List<Integer>> left = helper(root.left, target - root.val);
        List<List<Integer>> right = helper(root.right, target - root.val);
        
        for (List<Integer> path : left) {
            List<Integer> newPath = new ArrayList<Integer>();
            newPath.add(root.val);
            newPath.addAll(path);
            result.add(newPath);
        }
        
        for (List<Integer> path : right) {
            List<Integer> newPath = new ArrayList<Integer>();
            newPath.add(root.val);
            newPath.addAll(path);
            result.add(newPath);
        }
        
        return result;
    }
}


原文地址:https://www.cnblogs.com/jasminemzy/p/7669615.html