• leetcode: 树


    1. sum-root-to-leaf-numbers

    Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number.

    An example is the root-to-leaf path1->2->3which represents the number123.

    Find the total sum of all root-to-leaf numbers.

    For example,

        1
       / 
      2   3
    

    The root-to-leaf path1->2represents the number12.
    The root-to-leaf path1->3represents the number13.

    Return the sum = 12 + 13 =25.

    DFS算法解决即可

    /** 
     * Definition for binary tree 
     * public class TreeNode { 
     *     int val; 
     *     TreeNode left; 
     *     TreeNode right; 
     *     TreeNode(int x) { val = x; } 
     * } 
     */  
    public class Solution{
        public int sumNumbers(TreeNode root) {
        if(root == null) 
            return 0;
     
        return dfs(root, 0, 0);
        }
     
        public int dfs(TreeNode node, int num, int sum){
            if(node == null) return sum;
     
            num = num*10 + node.val;
     
            // leaf
            if(node.left == null && node.right == null) {
                sum += num;
                return sum;
            }
     
            // left subtree + right subtree
            sum = dfs(node.left, num, sum) + dfs(node.right, num, sum);
            return sum;
        }    
    }
    View Code

    2. binary-tree-maximum-path-sum 

    Given a binary tree, find the maximum path sum.

    The path may start and end at any node in the tree.

    For example:
    Given the below binary tree,

           1
          / 
         2   3

    Return6.

     二叉树最大路径和, 使用递归算法。

    关于某一个节点的最大路径可能有两种情况:1.是这个node向下走到某个点终止的一条路径,2. 是从该节点的左子树的某一个节点,跨过该节点,到该节点右子树某个节点终止的一条路径

    public int maxPathSum(TreeNode root) {
        int max[] = new int[1]; 
        max[0] = Integer.MIN_VALUE;
        calculateSum(root, max);
        return max[0];
    }
     
    public int calculateSum(TreeNode root, int[] max) {
        if (root == null)
            return 0;
     
        int left = calculateSum(root.left, max);
        int right = calculateSum(root.right, max);
     
        int current = Math.max(root.val, Math.max(root.val + left, root.val + right));
     
        max[0] = Math.max(max[0], Math.max(current, left + root.val + right));
     
        return current;
    }
    View Code

    3. populating-next-right-pointers-in-each-node

    Given a binary tree

        struct TreeLinkNode {
          TreeLinkNode *left;
          TreeLinkNode *right;
          TreeLinkNode *next;
        }
    

    Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set toNULL.

    Initially, all next pointers are set toNULL.

    Note:

    • You may only use constant extra space.  (常数 空间复杂度)
    • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).  (满二叉树)

    For example,
    Given the following perfect binary tree

             1
           /  
          2    3
         /   / 
        4  5  6  7

    After calling your function, the tree should look like:

             1 -> NULL
           /  
          2 -> 3 -> NULL
         /   / 
        4->5->6->7 -> NULL

    Solution 1:

    1.如果有左儿子(根据题目中说了为完全二叉树),所以肯定有右儿子,则把左子树的next节点赋值成右儿子。

    2.如果有右儿子,则判断根节点是否有next ,如果有,则将右儿子的next设置为根节点的next的左儿子。

    3.递归处理左儿子。

    4.递归处理右儿子。

    /* 递归处理左右子树. 这个算法可能会消耗O(h)的栈空间*/
        public void connect(TreeLinkNode root) {
            if (root == null) {
                return;
            }
            
            rec(root);
        }
    
        public void rec(TreeLinkNode root) {
            if (root == null) {
                return;
            }
    
            if (root.left != null) {
                root.left.next = root.right;            
            }
    
            if (root.right != null) {
                //包含两种情况:root.next是否为null
                root.right.next = root.next.left;
            }
            
            rec(root.left);
            rec(root.right);
        }
    View Code

    Solution2:

    使用2个循环,一个指针P1专门记录每一层的最左边节点,另一个指针P2扫描本层,把下一层的链接上。

    下层链接完成后,将P1移动到它的左孩子即可。这个算法的空间复杂度是O(1). 没有额外的空间。

    /**
     * Definition for binary tree with next pointer.
     * public class TreeLinkNode {
     *     int val;
     *     TreeLinkNode left, right, next;
     *     TreeLinkNode(int x) { val = x; }
     * }
     */
    public class Solution{
        public void connect(TreeLinkNode root) {
            if (root == null) {
                return;
            }
            
            TreeLinkNode leftEnd = root;
            while (leftEnd != null && leftEnd.left != null) {
                TreeLinkNode cur = leftEnd;
                while (cur != null) {
                    cur.left.next = cur.right;
                    cur.right.next = cur.next == null ? null: cur.next.left;
                    
                    cur = cur.next;
                }
                
                leftEnd = leftEnd.left;
            }
        }
    }
    View Code

    4. Path Sum leetcode java

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /        
            7    2      1
    

    return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

    S1:  递归

    public boolean hasPathSum(TreeNode root, int sum) {
            if(root == null) 
                return false;
            
            sum -= root.val;
            if(root.left == null && root.right==null)  
                return sum == 0;
            else 
                return hasPathSum(root.left,sum) || hasPathSum(root.right,sum);
        }
    View Code

    S2:非递归

    // 使用队列实现
    public boolean hasPathSum(TreeNode root, int sum) {
            if(root == null) return false;
     
            LinkedList<TreeNode> nodes = new LinkedList<TreeNode>();
            LinkedList<Integer> values = new LinkedList<Integer>();
     
            nodes.add(root);
            values.add(root.val);
     
            while(!nodes.isEmpty()){
                TreeNode curr = nodes.poll();
                int sumValue = values.poll();
     
                if(curr.left == null && curr.right == null && sumValue==sum){
                    return true;
                }
     
                if(curr.left != null){
                    nodes.add(curr.left);
                    values.add(sumValue+curr.left.val);
                }
     
                if(curr.right != null){
                    nodes.add(curr.right);
                    values.add(sumValue+curr.right.val);
                }
            }
     
            return false;
        }
    View Code

    5. path sum ii 

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

    For example:
    Given the below binary tree and sum = 22,

                  5
                 / 
                4   8
               /   / 
              11  13  4
             /      / 
            7    2  5   1
    

    return[

       [5,4,11,2],
       [5,8,4,5]
    ]

    除了要判断是否有这样的一个path sum,还需要把所有的都可能性结果都返回,所以就用传统的DFS递归解决子问题
    public List<ArrayList<Integer>> pathSum(TreeNode root, int sum) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
        if(root == null) 
            return result;
     
        ArrayList<Integer> l = new ArrayList<Integer>();
        l.add(root.val);
        dfs(root, sum-root.val, result, l);
        return result;
    }
     
    public void dfs(TreeNode t, int sum, ArrayList<ArrayList<Integer>> result, ArrayList<Integer> l){
        if(t.left==null && t.right==null && sum==0){
            ArrayList<Integer> temp = new ArrayList<Integer>();
            temp.addAll(l);
            result.add(temp);
        }
     
        //search path of left node
        if(t.left != null){
            l.add(t.left.val);
            dfs(t.left, sum-t.left.val, result, l);
            l.remove(l.size()-1);
        }
     
        //search path of right node
        if(t.right!=null){
            l.add(t.right.val);
            dfs(t.right, sum-t.right.val, result, l);
            l.remove(l.size()-1);
        }
    }
    View Code

    6. binary tree level order traversal ii 

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left to right, level by level from leaf to root).

    For example:
    Given binary tree {3,9,20,#,#,15,7},

        3
       / 
      9  20
        /  
       15   7
    

    return its bottom-up level order traversal as:

    [
      [15,7],
      [9,20],
      [3]
    ]

    public ArrayList<ArrayList<Integer>> levelOrderBottom(TreeNode root) {
            ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();  
            if(root == null)  
                return res;
            
            LinkedList<TreeNode> queue = new LinkedList<TreeNode>();  
            queue.add(root);
            
            int curLevCnt = 1;   //计数器,当前处理层个数
            int nextLevCnt = 0;  //下一层要处理的节点个数
            
            ArrayList<Integer> levelres = new ArrayList<Integer>();  
           
            while(!queue.isEmpty()){  
            
            // poll移除并返回队列头部元素
                TreeNode cur = queue.poll();  
                curLevCnt--;  
                levelres.add(cur.val);  
                
                if(cur.left != null){  
                    queue.add(cur.left);  
                    nextLevCnt++;  
                }  
                if(cur.right != null){  
                    queue.add(cur.right);  
                    nextLevCnt++;  
                }  
                  
                if(curLevCnt == 0){  
                    curLevCnt = nextLevCnt;  
                    nextLevCnt = 0;  
                    
                    res.add(0,levelres);  //insert one by one from the beginning
                    levelres = new ArrayList<Integer>();  
                }  
            }  
            return res;  
        }
    View Code


    7. balanced binary tree(平衡二叉树)

    Given a binary tree, determine if it is height-balanced.

    For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

    判断是否是平衡二叉树(Balanced Binary Tree)又被称为AVL树(有别于AVL算法),且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

    递归

    /**
     * Definition for binary tree
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode(int x) { val = x; }
     * }
     */
     
    
        public int checkBalanced(TreeNode t){
            if(t==null)
                return 0;
                
            int leftheight = checkBalanced(t.left);
            int rightheight = checkBalanced(t.right);
            if(rightheight == -1 || leftheight==-1)
                return -1;
            
            if(Math.abs(leftheight-rightheight)>1)
                return -1;
            else
                return Math.max(leftheight,rightheight)+1;
        }
        
        public boolean isBalanced(TreeNode root) {
            if(checkBalanced(root) == -1)
                return false;
            else
                return true;
        }
    View Code

    8. maximum depth of binary tree 

    Given a binary tree, find its maximum depth.

    The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

    求最大深度

    S1: 迭代

    public int maxDepth(TreeNode root) {
        if(root == null)
            return 0;
        
        int depth = 0;
        LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);
        int curNum = 1; //当前层节点个数
        int nextNum = 0; // 下一层节点个数
        
        while(!queue.isEmpty()){
            TreeNode n = queue.poll();
            curNum--;
            if(n.left!=null){
                queue.add(n.left);
                nextNum++;
            }
            if(n.right!=null){
                queue.add(n.right);
                nextNum++;
            }
            if(curNum == 0){
                curNum = nextNum;
                nextNum = 0;
                depth++;
            }
        }
        return depth;
    }
    View Code

    S2:递归

    public int maxDepth(TreeNode root) {
            if(root==null)
                return 0;
            int leftmax = maxDepth(root.left);
            int rightmax = maxDepth(root.right);
            return Math.max(leftmax, rightmax)+1;
        }
    View Code

    9. minimum depth of binary tree 

    Given a binary tree, find its minimum depth.

    The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

    最小深度

    S1: BFS,按层遍历,如果在某一层发现了一个叶子节点,就找到了最小深度

    public class Solution{
        public int minDepth(Treenode root){
            if(root==null)     
                return 0;
            int depth=1;
            int currentLevel=1;
            int nextLevel=0;
            Queue<TreeNode> queue=new LinkedList<TreeNode>();
            queue.add(root);
            
            while(!queue.isEmpty()){
                TreeNode node=queue.remove();
                currentLevel--;
                
                if(node.left==null && node.right==null)
                    return depth;
                
                if(node.left!=null){
                    queue.add(node.left);
                    nextLevel++;
                }
                
                if(node.right!=null){
                    queue.add(node.right);
                    nextLevel++;
                }
                
                if(currentLevel==0){
                    if(nextLevel!=0){
                        depth++;
                    }
                    currentLevel=nextLevel;
                    nextLevel=0;
                }
            }
            return depth;
        }
    }
    View Code

    S2: 递归,分别求左右子树的最小深度,返回较小值

    public class Solution{
        public int minDepth(Treenode root){
            if(root==null)
                return 0;
            if(root.left==null && root.right==null)
                return 1;
            else{
                int leftDepth=root.left!=null?minDepth(root.left):Integer.MAX_VALUE;
                int rightDepth=root.right!=null?minDepth(root.right):Integer.MAX_VALUE;
                
                return Math.min(leftDepth,rightDepth)+1;
            }
        }
    }
    View Code

    10.树的遍历

    1)bina tree postorder traversal(后序遍历)

    Given a binary tree, return thepostorder traversal of its nodes' values.

    For example:
    Given binary tree{1,#,2,3},

       1
        
         2
        /
       3
    

    return[3,2,1].

    Note: Recursive solution is trivial, could you do it iteratively?

    S1: 递归,时间复杂度O(n), 空间复杂度则是递归栈的大小即O(logn)

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }
     
     
    public class Solution {
        public ArrayList<Integer> postorderTraversal(TreeNode root) {
            ArrayList<Integer> res=new ArrayList<Integer>();
            helper(root,res);
            return res;
        }
        
        private void helper(TreeNode root, ArrayList<Integer> res){
            if(root==null)
                return;
            helper(root.left,res);
            helper(root.right,res);
            res.add(root.val);
        }
    }
    View Code

    S2:迭代,时间复杂度O(n),  空间复杂度O(logn)

    我们需要维护当前遍历的cur指针和前一个遍历的pre指针来追溯当前的情况(注意这里是遍历的指针,并不是真正按后序访问顺序的结点)。具体分为几种情况:

    (1)如果pre的左孩子或者右孩子是cur,那么说明遍历在往下走,按访问顺序继续,即如果有左孩子,则是左孩子进栈,否则如果有右孩子,则是右孩子进栈,如果左右孩子都没有,则说明该结点是叶子,可以直接访问并把结点出栈了。

    (2)如果反过来,cur的左孩子是pre,则说明已经在回溯往上走了,但是我们知道后序遍历要左右孩子走完才可以访问自己,所以这里如果有右孩子还需要把右孩子进栈,否则说明已经到自己了,可以访问并且出栈了。

    (3)如果cur的右孩子是pre,那么说明左右孩子都访问结束了,可以轮到自己了,访问并且出栈即可。

    2)Binary Tree Preorder Traversal(先序遍历)

    Given a binary tree, return the preorder traversal of its nodes’ values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3

    return [1,2,3].

    Note: Recursive solution is trivial, could you do it iteratively?

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x) { val = x; }
    }
     
    public class Solution {
        public ArrayList<Integer> preorderTraversal(TreeNode root) {
            ArrayList<Integer> returnList = new ArrayList<Integer>();
     
            if(root == null)
                return returnList;
     
            Stack<TreeNode> stack = new Stack<TreeNode>();
            stack.push(root);
            
            // 前序遍历,栈实现;
            //根节点出栈,右节点入栈,左节点入栈
            while(!stack.empty()){
                TreeNode n = stack.pop();
                returnList.add(n.val);
     
                if(n.right != null){
                    stack.push(n.right);
                }
                if(n.left != null){
                    stack.push(n.left);
                }
     
            }
            return returnList;
        }
    }
    View Code

    3)Binary Tree Inorder Traversal (中序遍历)

    Given a binary tree, return the inorder traversal of its nodes’ values.

    For example:
    Given binary tree {1,#,2,3},

       1
        
         2
        /
       3
    

    return [1,3,2].

    Note: Recursive solution is trivial, could you do it iteratively?

    S1:栈实现

    public class TreeNode {
         int val;
         TreeNode left;
         TreeNode right;
         TreeNode(int x) { val = x; }
     }
     
    public class Solution {
        public ArrayList<Integer> inorderTraversal(TreeNode root) {
      
             ArrayList<Integer> lst = new ArrayList<Integer>();
     
            if(root == null)
                return lst; 
     
            Stack<TreeNode> stack = new Stack<TreeNode>();
       
            TreeNode p = root;
     
            //中序遍历,左根右
            while(!stack.empty() || p != null){
     
                //左子树节点一直入栈;
                //如果没有左孩子,出栈,p指向其右孩子
                if(p != null){
                    stack.push(p);
                    p = p.left;
                }else{
                    TreeNode t = stack.pop();
                    lst.add(t.val);
                    p = t.right;
                }
            }
     
            return lst;
        }
    }
    View Code

    S2:递归

    public class Solution {
        List<Integer> result = new ArrayList<Integer>();
     
        public List<Integer> inorderTraversal(TreeNode root) {
            if(root !=null){
                helper(root);
            }
     
            return result;
        }
     
        //中序遍历,递归
        public void helper(TreeNode p){
            if(p.left!=null)
                helper(p.left);
     
            result.add(p.val);
     
            if(p.right!=null)
                helper(p.right);
        }
    }
    View Code

    11. validate binary search tree (二分查找树判断)

    Given a binary tree, determine if it is a valid binary search tree (BST).

    Assume a BST is defined as follows:

    • The left subtree of a node contains only nodes with keys less than the node's key.
    • The right subtree of a node contains only nodes with keys greater than the node's key.
    • Both the left and right subtrees must also be binary search trees.

     

    判断是否为二分查找树: 1)左子树的值<根结点的值; 2)根结点的值<右子树的值;3)左右子树也满足以上条件

    需要注意的是,左子树的所有节点都要比根节点小,而非只是其左孩子比其小,右子树同样。

    S1: 递归

    public boolean isValidBST(TreeNode root) {
        return isValidBST(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);    
    }
     
     
     //每次更新递归的上下界
    public boolean isValidBST(TreeNode p, double min, double max){
        if(p==null) 
            return true;
     
        if(p.val <= min || p.val >= max)
            return false;
     
        return isValidBST(p.left, min, p.val) && isValidBST(p.right, p.val, max);
    }
    View Code

    S2:迭代

    public class Solution {
        public boolean isValidBST(TreeNode root) {
            if(root == null)
                return true;
     
            LinkedList<BNode> queue = new LinkedList<BNode>();
            queue.add(new BNode(root, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
            while(!queue.isEmpty()){
                BNode b = queue.poll();
                if(b.n.val <= b.left || b.n.val >=b.right){
                    return false;
                }
                if(b.n.left!=null){
                    queue.offer(new BNode(b.n.left, b.left, b.n.val));
                }
                if(b.n.right!=null){
                    queue.offer(new BNode(b.n.right, b.n.val, b.right));
                }
            }
            return true;
        }
    }
    //define a BNode class with TreeNode and it's boundaries
    class BNode{
        TreeNode n;
        double left;
        double right;
        public BNode(TreeNode n, double left, double right){
            this.n = n;
            this.left = left;
            this.right = right;
        }
    }
    View Code

    12 unique binary search trees(寻找二分查找树个数)

    Given n, how many structurally unique BST's(binary search trees) that store values 1...n?

    For example,
    Given n = 3, there are a total of 5 unique BST's.

       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3

    <                       左子树值<根结点值<右子树的值                         > 

    如果集合为空,只有一种BST,即空树,
    UniqueTrees[0] =1

    如果集合仅有一个元素,只有一种BST,即为单个节点
    UniqueTrees[1] = 1

    UniqueTrees[2] = UniqueTrees[0] * UniqueTrees[1]   (1为根的情况)
                      + UniqueTrees[1] * UniqueTrees[0]  (2为根的情况。

    再看一遍三个元素的数组,可以发现BST的取值方式如下:
    UniqueTrees[3] = UniqueTrees[0]*UniqueTrees[2]  (1为根的情况)
                   + UniqueTrees[1]*UniqueTrees[1]  (2为根的情况)
                   + UniqueTrees[2]*UniqueTrees[0]  (3为根的情况)

    所以,由此观察,可以得出UniqueTrees的递推公式为
    UniqueTrees[i] = ∑ UniqueTrees[0...k] * [i-1-k]     k取值范围 0<= k <=(i-1)

    public int numTrees(int n) {
        int[] count = new int[n + 1];
     
        count[0] = 1;
        count[1] = 1;
     
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j <= i - 1; j++) {
                count[i] = count[i] + count[j] * count[i - j - 1];
            }
        }
     
        return count[n];
    }
    View Code

    13. unique binary search trees ii

    Given n, generate all structurally unique BST's (binary search trees) that store values 1...n.

    For example,
    Given n = 3, your program should return all 5 unique BST's shown below.

       1         3     3      2      1
               /     /      /       
         3     2     1      1   3      2
        /     /                        
       2     1         2                 3

    返回所有符合条件的二分查找树

    当数组为 1,2,3,4,.. i,.. n时,基于以下原则的BST建树具有唯一性:
    以i为根节点的树,其左子树由[1, i-1]构成, 其右子树由[i+1, n]构成。 
    public ArrayList<TreeNode> generateTrees(int n) {
            return generateTrees(1, n);//从1作为root开始,到n作为root结束
        }
         
        private ArrayList<TreeNode> generateTrees(int left, int right){
            ArrayList<TreeNode> res = new ArrayList<TreeNode>();
            if (left > right){
                res.add(null);
                return res;
            }
            for (int i = left; i <= right; i++){
                ArrayList<TreeNode> lefts = generateTrees(left, i-1);//以i作为根节点,左子树由[1,i-1]构成
                ArrayList<TreeNode> rights = generateTrees(i+1, right);//右子树由[i+1, n]构成
                for (int j = 0; j < lefts.size(); j++){
                    for (int k = 0; k < rights.size(); k++){
                        TreeNode root = new TreeNode(i);
                        root.left = lefts.get(j);
                        root.right = rights.get(k);
                        res.add(root);//存储所有可能行
                    }
                }
            }
            return res;
        }
    View Code

    14. symmetric tree(对称树)

    Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

    For example, this binary tree is symmetric:

        1
       / 
      2   2
     /  / 
    3  4 4  3

    But the following is not:

        1
       / 
      2   2
          
       3    3

    Note:
    Bonus points if you could solve it both recursively and iteratively.

    使用递归进行求解,先判断左右子结点是否相等,不等就返回false,相等就将左子结点的左子树与右子结果的右子结点进行比较操作,同时将左子结点的左子树与右子结点的左子树进行比较,只有两个同时为真是才返回true,否则返回false。 

    public class Solution {
        public boolean isSymmetric(TreeNode root) {
            if (root == null) {
                return true;
            }
            return isMirror(root.left, root.right);
        }
     
        public boolean isMirror(TreeNode leftNode, TreeNode rightNode) {
            if (leftNode == null && rightNode == null) {
                return true;
            } else if (
                (leftNode != null && rightNode == null) ||
                (leftNode == null && rightNode != null) ||
                leftNode.val != rightNode.val ||
                !isMirror(leftNode.left, rightNode.right) ||
                !isMirror(leftNode.right, rightNode.left)) {
                return false;
            } else {
                return true;
            }
        }
    }
    View Code

    15. recover binary search tree 

    Two elements of a binary search tree (BST) are swapped by mistake.

    Recover the tree without changing its structure.

    Note:

    A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

     解决方法是利用中序遍历找顺序不对的两个点,最后swap一下就好。

     简单而言,第一个逆序点要记录,最后一个逆序点要记录,最后swap一下。

     因为Inorder用了递归来解决,所以为了能存储这两个逆序点,这里用了全局变量,用其他引用型遍历解决也可以。

    public class Solution {
        TreeNode pre;
        TreeNode first;
        TreeNode second;
          
        public void inorder(TreeNode root){  
            if(root == null)  
                return;  
    
            inorder(root.left);  
            
            if(pre == null){  
                pre = root;  //pre指针初始
            }else{  
                if(pre.val > root.val){  
                    if(first == null){  
                        first = pre;//第一个逆序点
                    }  
                    second = root;  //不断寻找最后一个逆序点
                }  
                pre = root;  //pre指针每次后移一位
            }  
            
            inorder(root.right);  
            
        }  
          
        public void recoverTree(TreeNode root) {  
            pre = null;  
            first = null;  
            second = null;  
            inorder(root);  
            if(first!=null && second!=null){   
                int tmp = first.val;  
                first.val = second.val;  
                second.val = tmp;  
            }  
        }
    View Code

     

    16.  construct binary tree from preorder and inorder traversal (通过先序和中序遍历重构二叉树)

    public class Solution {
        private int findPosition(int[] arr, int start, int end, int key) {
            int i;
            for (i = start; i <= end; i++) {
                if (arr[i] == key) {
                    return i;
                }
            }
            return -1;
        }
    
        private TreeNode myBuildTree(int[] inorder, int instart, int inend,
                int[] preorder, int prestart, int preend) {
            if (instart > inend) {
                return null;
            }
    
            //前序的第一个是 “根结点”
            TreeNode root = new TreeNode(preorder[prestart]);  
            
            //在中序遍历中寻找该 “根结点”
            int position = findPosition(inorder, instart, inend, preorder[prestart]);
    
            root.left = myBuildTree(inorder, instart, position - 1,
                    preorder, prestart + 1, prestart + position - instart);
                    
            root.right = myBuildTree(inorder, position + 1, inend,
                    preorder, position - inend + preend + 1, preend);
                    
            return root; //返回该轮的“根结点”
        }
    
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            if (inorder.length != preorder.length) {
                return null;
            }
            return myBuildTree(inorder, 0, inorder.length - 1, preorder, 0, preorder.length - 1);
        }
    }
    View Code
  • 相关阅读:
    Egg 中使用 Mongoose 以及 Egg 中的 model
    Egg.js 中使用第三方插件以及 Egg.js 插件 egg-mongo-native 操作 mongodb 数据库
    egg定时任务
    jsx中给VUE绑定事件
    【T09】要认识到TCP是一个可靠的,但不是绝对可靠的协议
    PostgreSQL 高级SQL(五) 内建窗口函数
    PostgreSQL 高级SQL(四) 滑动窗口函数
    PostgreSQL 高级SQL(三) 窗口函数
    PostgreSQL 高级SQL(二) filter子句
    PostgreSQL 高级SQL(一)分组集
  • 原文地址:https://www.cnblogs.com/zxqstrong/p/5374164.html
Copyright © 2020-2023  润新知