zoukankan      html  css  js  c++  java
  • *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;
        }
    }


  • 相关阅读:
    EF中读取随机数据的问题
    【坐在马桶上看算法】算法3:最常用的排序——快速排序
    C#递归算法
    机器学习策略(二)---误差分析、训练集与开发测试集不相配怎么办、迁移学习/多任务学习、端到端深度学习
    机器学习策略(一)---正交化、评估指标、优化指标、训练与测试集数据集大小、可避免误差
    改善深层神经网络的优化算法:mini-batch梯度下降、指数加权平均、动量梯度下降、RMSprop、Adam优化、学习率衰减
    具有单隐藏层的二分类神经网络
    神经网络前向后向传播(理论与实战)
    梯度消失与梯度爆炸---如何选择随机初始权重
    正则化输入
  • 原文地址:https://www.cnblogs.com/jasminemzy/p/7669615.html
Copyright © 2011-2022 走看看