• 三、二叉树


    一、递归思想:递归的基本思想是把规模大的问题转化为规模小的相似的子问题来解决。在函数实现时,因为解决大问题的方法和解决小问题的方法往往是同一个方法,所以就产生了函数调用它自身的情况。另外这个解决问题的函数必须有明显的结束条件,这样就不会产生无限递归的情况了。(http://www.nowamagic.net/librarys/veda/detail/2314)

      1)遍历:结果在调用时作为参数传递;从顶到下的过程

      2)分治:结果在返回值里,不在调用中作为参数传递,从下到上(有递、无归)

      同:递归思想

    90%二叉数问题都可分治解决

    二叉树问题:

    1、树形分析时间复杂度计算=树中节点个数*每个节点的处理时间

    2、二叉树结构:

     * public class TreeNode {
     *     public int val;
     *     public TreeNode left, right;
     *     public TreeNode(int val) {
     *         this.val = val;
     *         this.left = this.right = null;
     *     }
     * }
    View Code

    3、二叉树遍历:

    递归:

    1)前:跟-左-右

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Preorder in ArrayList which contains node values.
         */
        public ArrayList<Integer> preorderTraversal(TreeNode root) {
            // write your code here
            //recursion
            ArrayList<Integer> res = new ArrayList<>();
            if (root == null) {
                return res;
            }
            traverse(root,res);
            return res;
        }
        private void traverse(TreeNode root, ArrayList<Integer> res) {
            if (root == null) {
                return;
            }
            res.add(root.val);
            traverse(root.left, res);
            traverse(root.right, res);
        }
    }
    View Code

    2中:左-根-右

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Inorder in ArrayList which contains node values.
         */
        public ArrayList<Integer> inorderTraversal(TreeNode root) {
            // write your code here
            ArrayList<Integer> result = new ArrayList<>();
            traverse(root, result);
            return result;
        }
        private void traverse(TreeNode root, ArrayList<Integer> result) {
            if (root == null) {
                return;
            }
            traverse(root.left, result);
            result.add(root.val);
            traverse(root.right,result);
        }
    }
    View Code

    3)后: 左- 右-中

    public ArrayList<Integer> postorderTraversal(TreeNode root) {
        ArrayList<Integer> result = new ArrayList<Integer>();
    
        if (root == null) {
            return result;
        }
    
        result.addAll(postorderTraversal(root.left));
        result.addAll(postorderTraversal(root.right));
        result.add(root.val);
    
        return result;   
    }
    View Code

    非递归

    前:2遍,带刷,not ac : root 和 treeNode 分错

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Preorder in ArrayList which contains node values.
         */
        public ArrayList<Integer> preorderTraversal(TreeNode root) {
            // write your code here
            //no - recusion
            ArrayList<Integer> result = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            if (root == null) {
                return result;
            }
            stack.push(root);
            while (!stack.empty()) {
                TreeNode treeNode = stack.pop();
                result.add(treeNode.val);
                if (treeNode.right != null) {
                    stack.push(treeNode.right);
                }
                if (treeNode.left != null) {
                    stack.push(treeNode.left);
                }
            }
            return result;
        }
    }
    View Code

    中:

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Inorder in ArrayList which contains node values.
         */
        public ArrayList<Integer> inorderTraversal(TreeNode root) {
            // write your code here
            ArrayList<Integer> result = new ArrayList<>();
            Stack<TreeNode> stack = new Stack<>();
            TreeNode node = root;
            while (node != null || !stack.empty()) {
                while (node != null) {//遍历到最左边
                    stack.push(node);
                    node = node.left;
                }
                node = stack.peek();//取出栈顶但不删除
                stack.pop();
                result.add(node.val);//把最左边的节点加入结果
                node = node.right;//该节点有右叶子吗?
            }
            return result;
        }
    }
    View Code

    后:not ac, 右回的时候忘了pop()

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: Postorder in ArrayList which contains node values.
         */
        public ArrayList<Integer> postorderTraversal(TreeNode root) {
            // write your code here
            ArrayList<Integer> result = new ArrayList<>();
            if (root == null) {
                return result;
            }
            TreeNode cur = root;
            TreeNode pre = null;
            Stack<TreeNode> stack = new Stack<>();
            stack.push(root);
            while (!stack.empty()) {
                cur = stack.peek();
                // trarve up the tree, 深度递归
                if (pre == null || pre.left == cur || pre.right == cur) {
                    if (cur.left != null) {
                        stack.push(cur.left);
                    } else if (cur.right != null){
                        stack.push(cur.right);
                    }
                } else if (cur.left == pre){//从左面回溯的
                    if (cur.right != null) {
                        stack.push(cur.right);
                    }
                } else {//从右边回溯的
                    result.add(cur.val);
                    stack.pop();
                }
                pre = cur;
            }
            return result;
        }
    }
    View Code

     4、二叉树的最大深度:

    (1) 分治法:ac

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: An integer.
         */
        private int depth;
        public int maxDepth(TreeNode root) {
            // write your code here
            if (root == null) {
                return 0;
            }
            int left = maxDepth(root.left);
            int right = maxDepth(root.right);
            depth = Math.max(left, right) + 1;
            return depth;
        }
    }
    View Code

    (2)travese:not ac :curdepth是结果,被传递,不断变化的

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: An integer.
         */
        private int depth;
        public int maxDepth(TreeNode root) {
            // write your code here
            depth = 0;
            helper(root, 1);
            return depth;
        }
        private void helper (TreeNode root, int curdepth) {
            if (root == null) {
                return;
            }
            if (curdepth > depth) {
                depth = curdepth;
            }
            helper(root.left, curdepth + 1);
            helper(root.right, curdepth + 1);
        }
    }
    View Code

    5、Binary Tree Paths(http://www.lintcode.com/en/problem/binary-tree-paths/):根节点到叶子节点的路径

    2遍,带看,ac: 

    分治法

    public class Solution {
        /**
         * @param root the root of the binary tree
         * @return all root-to-leaf paths
         */
        public List<String> binaryTreePaths(TreeNode root) {
            // Write your code here
            //分治法
            List<String> paths = new ArrayList<>();
            if (root == null) {
                return paths;
            }
            List<String> leftPaths = binaryTreePaths(root.left);
            List<String> rightPaths = binaryTreePaths(root.right);
            for (String path : leftPaths) {
                paths.add(root.val + "->" + path);
            }
            for (String path : rightPaths) {
                paths.add(root.val + "->" + path);
            }
            //root is a leaf
            if (paths.size() == 0) {
                paths.add("" + root.val);
            }
            return paths;
        }
    }
    View Code
    遍历法:not ac, 节点.val,String.valueOf()不懂,注意第一个String.valueOf()一定有,不然无法变为字符串
     
    public class Solution {
        /**
         * @param root the root of the binary tree
         * @return all root-to-leaf paths
         */
        public List<String> binaryTreePaths(TreeNode root) {
            // Write your code here
            //遍历
            List<String> results = new ArrayList<>();
            if (root == null) {
                return results;
            }
            helper(root, String.valueOf(root.val), results);
            return results;
        }
        private void helper(TreeNode root, String path, List<String> results) {
            if (root == null) {
                return;
            }
            if (root.left == null && root.right == null) {
                results.add(path);
                return;
            }
            if (root.left != null) {
                helper(root.left, path + "->" + String.valueOf(root.left.val), results);
            }
            if (root.right != null) {
                helper(root.right, path + "->" + String.valueOf(root.right.val), results);
            }
        }
    }
    View Code

    6、Minimum Subtree( http://www.lintcode.com/en/problem/minimum-subtree/):

    not ac : helper()返回错误,sum而不是subtreesum,sum下次还有继续用;

    第二遍:int sum = helper(root.left)+helper(root.right)+root.val,加了两遍left. notac

    思路:我们可以这样考虑:对于每一个节点,
    1. 如果它是空节点,那么就返回0
    2. 如果它有左子数,那么加上左子树的和
    3. 如果它有右子树,那么加上右子树的和
    简单来说,对于任何一个节点,我们不去考虑它下面还有多少儿子,只是考虑和它直接接触的左儿子和右儿子(如果存在的话)。如果到这个节点为止的和小于之前的和,那么就更新最小和,以及要回答的节点。

    public class Solution {
        /**
         * @param root the root of binary tree
         * @return the root of the minimum subtree
         */
        private TreeNode subtree = null;
        private int subtreeSum = Integer.MAX_VALUE;
        public TreeNode findSubtree(TreeNode root) {
            //Divserse + traverse
            helper(root);
            return subtree;
        }
        private int helper(TreeNode root) {
            if (root == null) {
                return 0;
            }
            int sum = helper(root.left) + helper(root.right) + root.val;
            if (sum < subtreeSum) {
                subtreeSum = sum;
                subtree = root;
            }
            return sum;
        }
    }
    View Code

     7、判断是否平衡二叉树:

    notac :class 要小写

    第一种:BOttom -UP o(n),o(n),當左子樹不平衡時,沒有必要再對右子樹求深度,要馬上 return -1,不可以把兩個判斷式寫在一起。

    ResultType:class ResultType { int var1, var2; }---创建一个type类,一个默认方法包含,boolean,maxdepth, type helper():当子树不是,根不是,空是,返回一个new type();

    2遍,注意helper()这个递归函数一定有一个终止条件,即对root== null 的处理在递归里。

    class ResultType {
        public boolean isBalanced;
        public int maxDepth;
        public ResultType (boolean isBalanced, int maxDepth) {
            this.isBalanced = isBalanced;
            this.maxDepth = maxDepth;
        }
    }
    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: True if this Binary tree is Balanced, or false.
         */
        
        public boolean isBalanced(TreeNode root) {
            // write your code here
            return helper(root).isBalanced;
        }
        private ResultType helper(TreeNode root) {
            if (root == null) {//root 空,是平衡二叉树
                return new ResultType (true, -1);
            }
            ResultType left = helper(root.left);
            ResultType right = helper(root.right);
            //leaf is not 
            if (!left.isBalanced || !right.isBalanced) {
                return new ResultType(false, -1);
            }
            //root is not
            if (Math.abs(left.maxDepth - right.maxDepth) > 1) {
                return new ResultType(false, -1);
            }
            return new ResultType(true, Math.max(left.maxDepth, right.maxDepth) + 1);
        }
    }
    View Code

    第二种:Top-down Recursion Approach;Time Complexity : t:O(n^2),s:o(n),但是 maxDepth() 會一直重複呼叫導致有重複計算的部分。

    构建int maxdepth函数,返回值判断 maxdepth != -1为真吗。

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: True if this Binary tree is Balanced, or false.
         */
        public boolean isBalanced(TreeNode root) {
            // write your code here
            return maxDepth(root) != -1;
        }
        public int maxDepth(TreeNode root) {
            if (root == null) {
                return 0;
            }
            int left = maxDepth(root.left);
            int right = maxDepth(root.right);
            //leaf is not 
            if (left == -1 || right == -1) {
                return -1;
            }
            //root is not
            if (Math.abs(left - right) > 1) {
                return -1;
            }
            return Math.max(left, right) + 1;
        }
    }
    View Code

    8、Subtree with Maximum Average  http://www.lintcode.com/problem/subtree-with-maximum-average/ 

    遍历+分治:遍历:从上往下递,分治从下往上的归,求resultsum.

    2.定义全局变量subtree,代表的是全局最大的average节点的信息,定义全局变量subtreeResult,内部包含全局最大average节点的sum和size
    3.定义一个返回值为ResultType的helper函数
    4.将问题递归简化,同时定义类型为ResultType的result变量,用于代表当前节点信息.

    2,只能构造一个resulttYpe类去处理。

    public class Solution {
        /**
         * @param root the root of binary tree
         * @return the root of the maximum average of subtree
         */
    private class ResultType {
        int sum;
        int size;
        public ResultType(int sum, int size) {
            this.sum = sum;
            this.size = size;
        }
    }
        private TreeNode subtree = null;
        private ResultType subtreeSum = null;
        public TreeNode findSubtree2(TreeNode root) {
            // Write your code here
            helper(root);
            return subtree;
        }
        public ResultType helper(TreeNode root) {
            if (root == null) {
                return new ResultType (0, 0);
            }
            ResultType left = helper(root.left);
            ResultType right = helper(root.right);
            ResultType result = new ResultType(left.sum + right.sum + root.val,
            left.size + right.size + 1);
            if (subtree == null || subtreeSum.sum * result.size < result.sum * subtreeSum.size) {
                subtree = root;
                subtreeSum = result;
            }
            return result;
        }
    }
    View Code

    9、Flattern Binary Tree to Linked List http://www.lintcode.com/problem/flatten-binary-tree-to-linked-list/

    1)、Non-Recursion

    public class Solution {
        /**
         * @param root: a TreeNode, the root of the binary tree
         * @return: nothing
         */
        public void flatten(TreeNode root) {
            // write your code here
            // no - curision
            if (root == null) {
                return;
            }
            Stack<TreeNode> stack = new Stack<>();
            stack.push(root);
            while (!stack.empty()) {
                TreeNode node = stack.pop();
                if (node.right != null) {
                    stack.push(node.right);
                }
                if (node.left != null) {
                    stack.push(node.left);
                }
                //connect:当前节点左制空,右边为堆栈弹出的节点
                node.left = null;
                if (stack.empty()) {
                    node.right = null;
                } else {
                    node.right = stack.peek();
                }
            }
        }
    }
    View Code

    2)、traverse : 2 not ac,每次要存下右节点的值

    查看http://www.jiuzhang.com/solutions/flatten-binary-tree-to-linked-list/

    blog:http://blog.csdn.net/linhuanmars/article/details/23717703   递归思路很详细:每次把pre 节点左节点制空,右节点置为当前节点。o(n),o(logn)

    10.0、Lowest Common Ancestor http://www.lintcode.com/problem/lowest-common-ancestor/ (A,B都在树中)

    前提:A,B都在树中

    1)divide + conquer :o(n)

    public class Solution {
        /**
         * @param root: The root of the binary search tree.
         * @param A and B: two nodes in a Binary.
         * @return: Return the least common ancestor(LCA) of the two nodes.
         */
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B) {
            // write your code here
            //divide + conquer o(n)
            if (root == null || root == A || root == B) {
                return root;
            }
            //divide
            TreeNode left = lowestCommonAncestor(root.left, A, B);
            TreeNode right = lowestCommonAncestor(root.right, A, B);
            //conquer
            if (left != null && right != null) {
                return root;
            }
            if (left != null) {
                return left;
            }
            if (right != null) {
                return right;
            }
            return null;
        }
    }
    View Code

    可以判定两个都不在树中

    /**
     * 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 the binary search tree.
         * @param A and B: two nodes in a Binary.
         * @return: Return the least common ancestor(LCA) of the two nodes.
         */
        public class Result {
            TreeNode node;
            boolean isAn;
            public Result (TreeNode node, boolean isAn) {
                this.node = node;
                this.isAn = isAn;
            }
        }
        public Result helper(TreeNode root, TreeNode A, TreeNode B) {
            // write your code here
            //divide + conquer o(n)
            if (root == null ) {
                return new Result(root, false);
            }
            if (root == A && root == B) {
                 return new Result(root, true);
            }
            //divide
            Result left = helper(root.left, A, B);
            if (left.isAn) {
                return left;
            }
            Result right = helper(root.right, A, B);
            if (right.isAn) {
                return right;
            }
            //conquer
            if (left.node != null && right.node != null) {
                return new Result(root, true);
            } else if (root == A || root == B) {
                boolean isAncestor = left.node != null || right.node != null ? true :false;
                return new Result(root,isAncestor);
            } else {
                return new Result(left.node != null ?left.node : right.node, false);
            }
        }
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode A, TreeNode B){
            Result is = helper(root, A, B);
            if (is.isAn) {
                return is.node;
            } else {
                return null; 
            }
    
        }
    }
    View Code

    2)如果是二叉查找树:

    public int query(Node t, Node u, Node v) {    
        int left = u.value;    
        int right = v.value;    
      
        //二叉查找树内,如果左结点大于右结点,不对,交换  
        if (left > right) {    
            int temp = left;    
            left = right;    
            right = temp;    
        }    
      
        while (true) {    
            //如果t小于u、v,往t的右子树中查找  
            if (t.value < left) {    
                t = t.right;    
      
            //如果t大于u、v,往t的左子树中查找  
            } else if (t.value > right) {    
                t = t.left;    
            } else {    
                return t.value;    
            }    
        }    
    }  
    View Code

    10.1、最近公共祖先 II (每个节点除了左右儿子指针以外,还包含一个父亲指针parent,指向自己的父亲。)

    思路:举例,找A,B的最近公共祖先。相当于找两个单链表的公共节点,用ArrayList<TreeNode> pathA,pathB 记录从A开始到根节点的路径,然后比较两个path的找出第一个不同的节点。

    /**
     * Definition of ParentTreeNode:
     * 
     * class ParentTreeNode {
     *     public ParentTreeNode parent, left, right;
     * }
     */
    public class Solution {
        /**
         * @param root: The root of the tree
         * @param A, B: Two node in the tree
         * @return: The lowest common ancestor of A and B
         */
        public ParentTreeNode lowestCommonAncestorII(ParentTreeNode root,
                                                     ParentTreeNode A,
                                                     ParentTreeNode B) {
            // Write your code here  
             ArrayList<ParentTreeNode> pathA = getParentPath2(A);
             ArrayList<ParentTreeNode> pathB = getParentPath2(B);
             int indexA = pathA.size() - 1;
             int indexB = pathB.size() - 1;
             ParentTreeNode ancestor = null;
             while (indexA >= 0 && indexB >= 0) {
                 if (pathA.get(indexA) != pathB.get(indexB)) {
                     break;
                 }
                 ancestor = pathA.get(indexA);
                 indexA--;
                 indexB--;
             }
            return ancestor;
        }
        public ArrayList<ParentTreeNode> getParentPath2 (ParentTreeNode root) {
            ArrayList<ParentTreeNode> path = new ArrayList<ParentTreeNode>();
            while (root != null) {
                path.add(root);
                root = root.parent;
            }
            return path;
        }
    }
    View Code

    10.3 最近公共祖先 III (A,B可能都不在树里)

    /**
     * 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;
     *     }
     * }
     */
     
    class ResultType {
        public boolean a_exist, b_exist;
        public TreeNode node;
        ResultType(boolean a, boolean b, TreeNode n) {
            a_exist = a;
            b_exist = b;
            node = n;
        }
    }
    
    public class Solution {
        /**
         * @param root The root of the binary tree.
         * @param A and B two nodes
         * @return: Return the LCA of the two nodes.
         */
        public TreeNode lowestCommonAncestor3(TreeNode root, TreeNode A, TreeNode B) {
            // write your code here
            ResultType rt = helper(root, A, B);
            if (rt.a_exist && rt.b_exist)
                return rt.node;
            else
                return null;
        }
    
        public ResultType helper(TreeNode root, TreeNode A, TreeNode B) {
            if (root == null)
                return new ResultType(false, false, null);
                
            ResultType left_rt = helper(root.left, A, B);
            ResultType right_rt = helper(root.right, A, B);
            
            boolean a_exist = left_rt.a_exist || right_rt.a_exist || root == A;
            boolean b_exist = left_rt.b_exist || right_rt.b_exist || root == B;
            
            if (root == A || root == B)
                return new ResultType(a_exist, b_exist, root);
    
            if (left_rt.node != null && right_rt.node != null)
                return new ResultType(a_exist, b_exist, root);
            if (left_rt.node != null)
                return new ResultType(a_exist, b_exist, left_rt.node);
            if (right_rt.node != null)
                return new ResultType(a_exist, b_exist, right_rt.node);
    
            return new ResultType(a_exist, b_exist, null);
        }
    }
    View Code

    11、Binary Tree Longest Consecutive Sequence http://www.lintcode.com/problem/binary-tree-longest-consecutivesequence/

    public class Solution {
        /**
         * @param root the root of binary tree
         * @return the length of the longest consecutive sequence path
         */
        public int longestConsecutive(TreeNode root) {
            //tranverse + divide
            return helper(root, null, 0);
        }
        public int helper(TreeNode root, TreeNode parent, int lengthwithoutroot) {
            if (root == null) {
                return 0;
            }
            int length = (parent != null && parent.val + 1 == root.val) ? 
                        lengthwithoutroot + 1 : 1;
            int left = helper(root.left, root, length);
            int right = helper(root.right, root, length);
            return Math.max(length, Math.max(left,right));
        }
    }
    View Code

    12、Binary Tree Path Sum I http://www.lintcode.com/problem/binary-tree-path-sum/   从根出发

    not ac:is leaf 

    public class Solution {
        /**
         * @param root the root of binary tree
         * @param target an integer
         * @return all valid paths
         */
        public List<List<Integer>> binaryTreePathSum(TreeNode root, int target) {
            // Write your code here
            List<List<Integer>> results = new ArrayList<>();
            if (root == null) {
                return results;
            }
            List<Integer> path = new ArrayList<Integer>();
            path.add(root.val);
            helper(root, root.val, path, results, target);
            return results;
        }
        private void helper(TreeNode root, int sum,
                            List<Integer> path, 
                            List<List<Integer>> results,
                            int target) {
            //meet leaf                    
            if (root.left == null && root.right == null) {
                if (sum == target) {
                    results.add(new ArrayList<Integer>(path));
                }
            }
            //go left
            if (root.left != null) {
                path.add(root.left.val);
                helper(root.left, sum + root.left.val, path, results, target);
                path.remove(path.size() - 1);
            }
            //go right
            if (root.right != null) {
                path.add(root.right.val);
                helper(root.right, sum + root.right.val, path, results, target);
                path.remove(path.size() - 1);
            }
            
                            }
    }
    View Code

    13、Binary Tree Path SumII  http://www.lintcode.com/problem/binary-tree-path-sum-ii/  任意节点出发,但是层级递增的

        public List<List<Integer>> binaryTreePathSum2(TreeNode root, int target) {
            // Write your code here
            List<List<Integer>> results = new ArrayList<>();
            if (root == null) {
                return results;
            }
            List<Integer> path = new ArrayList<>();
            helper(root, target, path, results, 0);
            return results;
        }
        private void helper(TreeNode head, int sum,List<Integer> path,
                            List<List<Integer>> results, int level) {
            if (head == null) {
                return;
            }
            int temp = sum;
            path.add(head.val);
            for (int i = level; i >= 0; i--) {
                temp -= path.get(i);
                if (temp == 0) {
                    List<Integer> tmp = new ArrayList<Integer> ();
                    for (int j = i; j <= level; j++) {
                        tmp.add(path.get(j));
                    }
                    results.add(tmp);
                }
            }
            helper(head.left, sum, path, results, level + 1);
            helper(head.right, sum, path, results, level + 1);
            path.remove(path.size() - 1);
                            }
    }
    View Code

    14.Binary Tree Path SumIII  

    public class Solution {
        /**
         * @param root the root of binary tree
         * @param target an integer
         * @return all valid paths
         */
        public List<List<Integer>> binaryTreePathSum3(ParentTreeNode root, int target) {
            // Write your code here
            List<List<Integer>> results = new ArrayList<>();
            dfs(root, target, results);
            return results;
        }
        private void dfs(ParentTreeNode root, int target, List<List<Integer>> results) {
            if (root == null) {
                return;
            }
            List<Integer> path = new ArrayList<Integer>();
            findSum(root, null, path, results, target);
            dfs(root.left, target, results);
            dfs(root.right, target, results);
        }
        private void findSum(ParentTreeNode root, ParentTreeNode father,
                            List<Integer> path, List<List<Integer>> results, int target) {
            path.add(root.val);
            target -= root.val;
            if (target == 0) {
                List<Integer> tmp = new ArrayList<Integer>();
                Collections.addAll(tmp, new Integer [path.size()]);
                Collections.copy(tmp, path);
                results.add(tmp);
            }
            if (root.parent != null && root.parent != father) {
                findSum(root.parent, root, path, results, target);
            }
            if (root.left != null && root.left != father) {
                findSum(root.left, root, path, results, target);
            }
            if (root.right != null && root.right != father) {
                findSum(root.right, root, path, results, target);
            }
            path.remove(path.size() - 1);
        }
    }
    View Code

    三、二叉查找树:

    性质:1.左子树小于跟

    从定义出发: • 左子树都比根节点小  left <= root

           • 右子树都不小于根节点 root < right

    从效果出发: • 中序遍历 in-order traversal 是“不下降”序列

           • 如果一棵二叉树的中序遍历不是“不下降”序列,则一定不是BST

           • 如果一棵二叉树的中序遍历是不下降,也未必是BST

    1、Validate Binary Search Tree http://www.lintcode.com/problem/validate-binary-search-tree/ (都是严格小于和大于)

    方法一:一个变量last存放当上一个节点的值,中序遍历二叉树,比较当前节点和last,但无法处理  【10,#,20】和【10,20】的情况 ,只能当满足 root.left < root <root.right适用

    not ac :int ---long ,对当前节点判断应该是《=

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: True if the binary tree is BST, or false
         */
        public long last = Long.MIN_VALUE;
        public boolean isValidBST(TreeNode root) {
            // write your code here
            if (root == null) {
                return true;
            }
            //检查左子树
            if (!isValidBST(root.left)) {
                return false;
            }
            //检查当前节点
            if (root.val <= last) {
                return false;
            }
            last = root.val;
            //检查右子树
            if (!isValidBST(root.right)) {
                return false;
            }
            return true;
        }
    }
    View Code

    方法二:最大、最小法:min = INTEGER.MIN,max =INTEGER.MAX,每个节点都进行判断  cur.left <= cur<cur.right当进入左子树,更新min,当进入右子树更新max

    not ac : int 换为 long

    public class Solution {
        /**
         * @param root: The root of binary tree.
         * @return: True if the binary tree is BST, or false
         */
        private long min = Long.MIN_VALUE;
        private long max = Long.MAX_VALUE;
        public boolean isValidBST(TreeNode root) {
            // write your code here
            return isValidhelper(root, min, max);
        }
        private boolean isValidhelper(TreeNode root, long min, long max) {
            if (root == null) {
                return true;
            }
            if (root.val <= min || root.val >= max) {
                return false;
            }
            if (!isValidhelper(root.left, min, root.val) 
            || !isValidhelper(root.right, root.val, max)){
                return false;
            }
            return true;
        }
    }
    View Code

     2、Convert Binary Search Tree to Doubly Linked List    http://www.lintcode.com/problem/convert-binary-search-tree-to-do ubly-linked-list/

  • 相关阅读:
    完美解决ListView中事件ItemCreated中使用ClientID导致插入数据失败
    cookie 和session 的区别详解
    ref与out之间的区别整理
    showModalDialog介绍
    meta元素
    [转] Spring Boot特性
    [转] Spring Boot 揭秘与实战(二) 数据存储篇
    Jsch初步
    如何通俗的解释交叉熵与相对熵
    pip安装时的异常,找不到lib2to3\Grammar.txt
  • 原文地址:https://www.cnblogs.com/lingli-meng/p/6532628.html
Copyright © 2020-2023  润新知