zoukankan      html  css  js  c++  java
  • 算法:二叉树


    1. Maximum Depth of Binary Tree: https://leetcode.com/problems/maximum-depth-of-binary-tree/

    最大深度:

    解法1:<Recursive>

    1 public class Solution {
    2     public int maxDepth(TreeNode root) {
    3         if (root == null) return 0;
    4         int rst = Math.max(maxDepth(root.left), maxDepth(root.right));
    5         return rst + 1;
    6     }
    7 }
    View Code

    解法2:<Iterative>(层序遍历思想: queue+size+cnt;)

    public class Solution {
        public int maxDepth(TreeNode root) {
            //Iterative--层序遍历思想
            if (root == null) return 0;
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            int cnt = 0;
            while (!queue.isEmpty()) {
                int size = queue.size();
                for (int i = 0; i < size; i++) {
                    TreeNode cur = queue.poll();
                    if (cur.left != null) queue.offer(cur.left);
                    if (cur.right != null) queue.offer(cur.right);
                }
                cnt++;
            }
            return cnt;
        }
    }
    View Code

     

    2. Minimum Depth of Binary Tree:https://leetcode.com/problems/minimum-depth-of-binary-tree/

    最小深度:

    解法1:<Recursice>(左节点为null返回右边的min+1;右节点为null返回左边的min+1;都不为null则返回Math.min()+1;)

    1 public class Solution {
    2     public int minDepth(TreeNode root) {
    3         if (root == null) return 0;
    4         if (root.left == null) return minDepth(root.right) + 1;
    5         if (root.right == null) return minDepth(root.left) + 1;
    6         int rst = Math.min(minDepth(root.left), minDepth(root.right));
    7         return rst + 1;
    8     }
    9 }
    View Code

    解法2:<Iterative>(层序遍历思想;找到第一个叶节点就返回。max的初始cnt是零,因为它是最后循环结束后return的。而min初始cnt是1,因为它是在循环内部return的,最后的cnt改为cnt+1+2等等都不会错。)

    public class Solution {
        public int minDepth(TreeNode root) {
            if (root == null) return 0;
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            int count = 1;
            while (!queue.isEmpty()) {
                int size = queue.size();
                for (int i = 0; i < size; i++) {
                    TreeNode node = queue.poll();
                    if (node.left == null && node.right == null) return count;
                    if (node.left != null) queue.offer(node.left);
                    if (node.right != null) queue.offer(node.right);
                }
                count++;
            }
            return count;
        }
    }
    View Code

    3. Binary Tree Inorder Traversal:https://leetcode.com/problems/binary-tree-inorder-traversal/

    中序遍历:

    解法1:<Recursive>(addAll)

    public class Solution {
        public List<Integer> inorderTraversal(TreeNode root) {
            List<Integer> rst = new ArrayList<>();
            if (root == null) return rst;
            rst.addAll(inorderTraversal(root.left));
            rst.add(root.val);
            rst.addAll(inorderTraversal(root.right));
            return rst;
        }
    }
    View Code

    解法2:<Iterative>(1.外循环while(||);2.内循环-入栈,左移;3.出栈,添值,右移)(中序遍历循环两个判断条件是因为 root不是提前push的,而前序遍历是提前push进root的)

    public class Solution {
        public List<Integer> inorderTraversal(TreeNode root) {
            List<Integer> rst = new ArrayList<Integer>();
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode cur = root;
            while (cur != null || !stack.empty()) {
                while (cur != null) {
                    stack.push(cur);
                    cur = cur.left;
                }
                cur = stack.pop();
                rst.add(cur.val);
                cur = cur.right;
            }
            return rst;
        }
    }
    View Code

    4. Binary Tree Preorder Traversal: https://leetcode.com/problems/binary-tree-preorder-traversal/

    前序遍历:(放入root; while(!empty), 出栈,添值,右左入栈)

    解法:<Iterative>

     1 public class Solution {
     2     public List<Integer> preorderTraversal(TreeNode root) {
     3         List<Integer> rst = new ArrayList<>();
     4         Stack<TreeNode> stack = new Stack<>();
     5         if (root == null) return rst;
     6         stack.push(root);
     7         while (!stack.empty()) {
     8             TreeNode cur = stack.pop();
     9             rst.add(cur.val);
    10             if (cur.right != null) stack.push(cur.right);
    11             if (cur.left != null) stack.push(cur.left);
    12         }
    13         return rst;
    14     }
    15 }
    View Code

    5. Binary Tree Postorder Traversal: https://leetcode.com/problems/binary-tree-postorder-traversal/

    后序遍历:(pre-NLR, post-LRN, ArrayList.add(0,val)直接得到LRN;  和前序遍历区别:list;左右入栈)

    解法:<Iterative>

    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root == null) return list;
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.empty()){
            root = stack.pop();
            list.add(0, root.val);
            if(root.left != null) stack.push(root.left);
            if(root.right != null) stack.push(root.right);
        }
        return list;
    }
    View Code

    6. Binary Tree Level Order Traversal: https://leetcode.com/problems/binary-tree-level-order-traversal/

    层序遍历:(queue+size/list+add/左右入列)

    解法:<Iterative>

    public class Solution {
        public List<List<Integer>> levelOrder(TreeNode root) {
            Queue<TreeNode> queue = new LinkedList<>();
            List<List<Integer>> rst = new ArrayList<>();
            if (root == null) return rst;
            queue.offer(root);
            while (!queue.isEmpty()) {
                List<Integer> list = new ArrayList<>();
                int size = queue.size();
                for (int i = 0; i < size; i++){
                    TreeNode node = queue.poll();
                    list.add(node.val);
                    if (node.left != null) queue.offer(node.left);
                    if (node.right != null) queue.offer(node.right);
                }
                rst.add(list);
            }
            return rst;
        }
    }
    View Code

    7. Binary Tree Level Order Traversal II:https://leetcode.com/problems/binary-tree-level-order-traversal-ii/

    层序遍历II-页到根顺序:

    解法:(与Level Order Traverse 方法相同。队列。利用LinkedList的addFirst方法。ps:rst为List<List<>>时不存在addFirst方法, 必须是LinkdeList<List<>>。也可以用ArrayList和LinkedList的add(index, E)的方法)

    public class Solution {
        public List<List<Integer>> levelOrderBottom(TreeNode root) {
            Queue<TreeNode> queue = new LinkedList<>();
            LinkedList<List<Integer>> rst = new LinkedList<>();
            if (root == null) return rst;
            queue.offer(root);
            while (!queue.isEmpty()) {
                int size = queue.size();
                List<Integer> list = new LinkedList<>();
                for (int i = 0; i < size; i++) {
                    TreeNode node = queue.poll();
                    list.add(node.val);
                    if (node.left != null) queue.offer(node.left);
                    if (node.right != null) queue.offer(node.right);
                }
                rst.addFirst(list);
            }
            return rst;
        }
    }
    View Code

    8. Binary Tree Zigzag Level Order Traversal: https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/

    曲折层序遍历(每层依次左右、右左、左右……):

    解法:<BFS>(和层序遍历方法相同。增加order作为boolean判断来选择list.add和list.add(0,val))

     1 public class Solution {
     2     public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
     3         List<List<Integer>> rst = new LinkedList<>();
     4         Queue<TreeNode> queue = new LinkedList<>();
     5         if (root == null) return rst;
     6         queue.offer(root);
     7         boolean order = true;
     8         while (!queue.isEmpty()) {
     9             int size = queue.size();
    10             List<Integer> list = new LinkedList<>();
    11             for (int i = 0; i < size; i++) {
    12                 TreeNode node = queue.poll();
    13                 if (order) {
    14                     list.add(node.val);
    15                 } else {
    16                     list.add(0, node.val);
    17                 }
    18                 if (node.left != null) queue.offer(node.left);
    19                 if (node.right != null) queue.offer(node.right);
    20             }
    21             order = !order;
    22             rst.add(list);
    23         }
    24         return rst;
    25     }
    26 }
    View Code

    9. Symmetric Tree: https://leetcode.com/problems/symmetric-tree/

    对称树:

    解法1:<Recursive>(左节点和右节点的比较,所以需要helper函数,判断left和right的null与val;递归左左和右右,左右和右左)

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

    解法2:<Iterative>(Stack, 每次pop两个对称的节点,判断两个节点是否满足条件。再push进四个节点)

    public class Solution {
        public boolean isSymmetric(TreeNode root) {
            if (root == null) return true;
            Stack<TreeNode> stack = new Stack<>();
            stack.push(root.left);
            stack.push(root.right);
            while (!stack.empty()) {
                TreeNode n1 = stack.pop(), n2 = stack.pop();
                if (n1 == null && n2 == null) continue;
                if (n1 == null || n2 == null || n1.val != n2.val) return false;
                stack.push(n1.right);
                stack.push(n2.left);
                stack.push(n1.left);
                stack.push(n2.right);
            }
            return true;
        }
    }
    View Code

    10. Same Tree: https://leetcode.com/problems/same-tree/

    判断两树是否相同:

    Recursive解法:(判断null,判断值,迭代)

    public class Solution {
        public boolean isSameTree(TreeNode p, TreeNode q) {
            if (p == null && q == null) return true;
            if (p != null && q !=null && p.val == q.val)
                return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
            return false;
        }
    }
    View Code

    Iterative解法:(首先判断head; 每次push左右节点,并且push一个节点都要比较size-有null不同则返回false;每次pop一个节点比较值是否相等;)

    public class Solution {
        public boolean isSameTree(TreeNode p, TreeNode q) {
            if (p == null && q == null) return true;
            if (p == null || q == null || p.val != q.val) return false;
            Stack<TreeNode> stack1 = new Stack<>();
            Stack<TreeNode> stack2 = new Stack<>();
            stack1.push(p);
            stack2.push(q);
            while (!stack1.empty()){
                TreeNode cur1 = stack1.pop();
                TreeNode cur2 = stack2.pop();
                if (cur1.val != cur2.val) return false;
                if (cur1.left != null) stack1.push(cur1.left);
                if (cur2.left != null) stack2.push(cur2.left);
                if (stack1.size() != stack2.size()) return false;
                if (cur1.right != null) stack1.push(cur1.right);
                if (cur2.right != null) stack2.push(cur2.right);
                if (stack1.size() != stack2.size()) return false;
            }
            return true;
        }
    }
    View Code

    11. Invert Binary Tree: https://leetcode.com/problems/invert-binary-tree/

    反转二叉树:

    解法1:(Recursive)

    public class Solution {
        public TreeNode invertTree(TreeNode root) {
            if (root == null) return root;
            TreeNode tmp = invertTree(root.right);
            root.right = invertTree(root.left);
            root.left = tmp;
            return root;
        }
    }
    View Code

    解法2:(Iterative 层序遍历思想 queue+swap+offer)

    public class Solution {
        public TreeNode invertTree(TreeNode root) {
            if (root == null) return null;
            Queue<TreeNode> queue = new LinkedList<>();
            queue.offer(root);
            while (!queue.isEmpty()) {
                TreeNode node = queue.poll();
                //swap;
                TreeNode tmp = node.right;
                node.right = node.left;
                node.left = tmp;
                //offer;
                if (node.left != null) queue.offer(node.left);
                if (node.right != null) queue.offer(node.right);
            }
            return root;
        }
    }
    View Code

    12. Balanced Binary Tree:https://leetcode.com/problems/balanced-binary-tree/

    平衡二叉树(两个子树的深度差不超过1):

    解法1:(利用方法depth,要求两个子树深度差小于1且两个子树均为平衡树)

    (1.if,rst,return 1&& ;  2.depth(),if-0,rst,return rst+1)

    public class Solution {
        public boolean isBalanced(TreeNode root) {
            if (root == null) return true;
            int rst = Math.abs(depth(root.left) - depth(root.right));
            return (rst <= 1) && isBalanced(root.left) && isBalanced(root.right);
        }
        public int depth(TreeNode root) {
            if (root == null) return 0;
            int rst = Math.max(depth(root.left), depth(root.right));
            return rst + 1;
        }
    }
    View Code

    解法2:(只遍历一次 用-1记录不平衡的子树;相当于自底向上遍历。解法1中首先root求左右深度O(N), 然后每个节点都要求左右深度, 所以是O(NlogN)? 而解法2每次返回节点的高度或者-1 最后判断值是否是-1即可,O(N))

    (1.return !=-1;  2.height: lh-if,rh-if; if(>1); return max()+1;)

    public class Solution {
        public boolean isBalanced(TreeNode root) {
            return height(root) != -1;
        }
        public int height(TreeNode root) {
            if (root == null) return 0;
            int lh = height(root.left);
            if (lh == -1) return -1;
            int rh = height(root.right);
            if (rh == -1) return -1;
            if (Math.abs(lh - rh) > 1) return -1;
            return Math.max(lh, rh) + 1;
        }
    }
    View Code

    13. Validate Binary Search Tree: https://leetcode.com/problems/validate-binary-search-tree/

    验证二叉搜索树:

    解法1:(递归;helper(root, lo, hi);判断每一节点是否在其所属范围之内)

    public class Solution {
        public boolean isValidBST(TreeNode root) {
            return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);
        }
        public boolean helper(TreeNode root, long lo, long hi) {
            if (root == null) return true;
            if (root.val >= hi || root.val <= lo) return false;
            return helper(root.left, lo, root.val) && helper(root.right, root.val, hi);
        }
    }
    View Code

    解法2:(迭代;中序遍历思想-中序遍历出来的数即为升序;pre记录前一节点;)

    public class Solution {
        public boolean isValidBST(TreeNode root) {
            Stack<TreeNode> stack = new Stack<>();
            TreeNode cur = root;
            TreeNode pre = null;
            while (cur != null || !stack.empty()) {
                while (cur != null) {
                    stack.push(cur);
                    cur = cur.left;
                }
                cur = stack.pop();
                if (pre != null && pre.val >= cur.val) return false;
                pre = cur;
                cur = cur.right;
            }
            return true;
        }
    }
    View Code

    14. Lowest Common Ancestor of a Binary Search Tree: https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/

    BST-最低公共祖先:

    解法1:(递归)(利用BST的特性,比两个都大则递归左边,比两个都小则递归右边)

    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if(root.val > p.val && root.val > q.val){
                return lowestCommonAncestor(root.left, p, q);
            }else if(root.val < p.val && root.val < q.val){
                return lowestCommonAncestor(root.right, p, q);
            }else{
                return root;
            }
        }
    }
    View Code

    解法2:(迭代)(与递归类似,while(true)里迭代)

    public class Solution {
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            while (true) {
                if (root.val > p.val && root.val > q.val)
                    root = root.left;
                else if (root.val < p.val && root.val < q.val)
                    root = root.right;
                else
                    return root;
            }
        }
    }
    View Code

    15. Lowest Common Ancestor of a Binary Tree:https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/

    最低公共祖先:

    解法:(递归 root为最低祖先条件是A和B分别在左右子树; )

    (如果找到了就返回LCA;如果只找到A就返回A;只找到B就返回B;左右不为空返回root;左空返回右,右空返回左)

    (具体:1.null/A/B 返回root;2.递归得left/right;3.左右非空返回root,有空的则返回非空)

    public class Solution {
        // 在root为根的二叉树中找A,B的LCA:
        // 如果找到了就返回这个LCA
        // 如果只碰到A,就返回A
        // 如果只碰到B,就返回B
        // 如果都没有,就返回null
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode node1, TreeNode node2) {
            if (root == null || root == node1 || root == node2) {
                return root;
            }
            
            // Divide
            TreeNode left = lowestCommonAncestor(root.left, node1, node2);
            TreeNode right = lowestCommonAncestor(root.right, node1, node2);
            
            // Conquer
            if (left != null && right != null) {
                return root;
            } 
            if (left != null) {
                return left;
            }
            if (right != null) {
                return right;
            }
            return null;
        }
    }
    View Code

    16. Path Sum: https://leetcode.com/problems/path-sum/

    判断是否存在根到叶路径经过的值的和等于给定值:

    解法:<Recursive>

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

    17. Path Sum II:https://leetcode.com/problems/path-sum-ii/

    返回路径值:

    解法:<Recursion>(和数组里子集的题类似。每次add进当前值,递归left和right,再remove即返回上一节点。终止条件是叶节点--及左右子节点都为null,如果=val了,那么add,remove,return;否则return;)

    public class Solution {
        public List<List<Integer>> pathSum(TreeNode root, int sum) {
            List<List<Integer>> rst = new ArrayList<>();
            List<Integer> list = new ArrayList<>();
            helper(root, sum, list, rst);
            return rst;
        }
        public void helper(TreeNode root, int sum, List<Integer> list, List<List<Integer>> rst) {
            if (root == null) return;
            if (root.left == null && root.right == null) {
                if (root.val == sum) {
                    list.add(root.val);
                    rst.add(new ArrayList<Integer>(list));
                    list.remove(list.size() - 1);
                }
                return;
            }
            list.add(root.val);
            helper(root.left, sum - root.val, list, rst);
            helper(root.right, sum - root.val, list, rst);
            list.remove(list.size() - 1);
        }
    }
    View Code

    18.Construct Binary Tree from Preorder and Inorder Traversal: http://www.lintcode.com/en/problem/construct-binary-tree-from-preorder-and-inorder-traversal/

    根据前序遍历和中序遍历构造树:

    (TreeNode helper(in,pre,inS,inE,preS); 如果(pre>len||inS>inE)null; 找出in中位置;递归得出left,right)

    public class Solution {
        /**
         *@param preorder : A list of integers that preorder traversal of a tree
         *@param inorder : A list of integers that inorder traversal of a tree
         *@return : Root of a tree
         */
        public TreeNode buildTree(int[] preorder, int[] inorder) {
            // write your code here
            return helper(preorder, inorder, 0, 0, inorder.length - 1);
        }
        public TreeNode helper(int[] pre, int[] in, int preStart, int inStart, int inEnd) {
            if (preStart > pre.length || inStart > inEnd) return null;
            TreeNode root = new TreeNode(pre[preStart]);
            int index = 0;
            for (int i = inStart; i <= inEnd; i++) {
                if (in[i] == pre[preStart]) {
                    index = i;
                    break;
                }
            }
            root.left = helper(pre, in, preStart + 1, inStart, index - 1);
            root.right = helper(pre, in, preStart + index- inStart + 1, index + 1, inEnd);
            return root;
        }
    }
    View Code

    19. Construct Binary Tree from Inorder and Postorder Traversal: https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

    根据中序遍历和后序遍历构造树:

    (helper(in,post,inS,inE,postE); 如果(preE<0||inS>inE)null; 找出in中位置;递归;)

    public class Solution {
        public TreeNode buildTree(int[] inorder, int[] postorder) {
            return helper(inorder, postorder, postorder.length - 1, 0, inorder.length - 1);
        }
        public TreeNode helper(int[] in, int[] post, int postEnd, int inStart, int inEnd) {
            if (postEnd < 0 || inStart > inEnd) return null;
            TreeNode root = new TreeNode(post[postEnd]);
            int index = 0;
            for (int i = inStart; i <= inEnd; i++) {
                if (in[i] == post[postEnd]) {
                    index = i;
                    break;
                }
            }
            root.left = helper(in, post, postEnd - inEnd + index - 1, inStart, index - 1);
            root.right = helper(in, post, postEnd - 1, index + 1, inEnd);
            return root;
        }
    }
    View Code

  • 相关阅读:
    88. Merge Sorted Array
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    83. Remove Duplicates from Sorted List
    82. Remove Duplicates from Sorted List II
    81. Search in Rotated Sorted Array II
    80. Remove Duplicates from Sorted Array II
    计算几何——点线关系(叉积)poj2318
  • 原文地址:https://www.cnblogs.com/buwenyuwu/p/6587887.html
Copyright © 2011-2022 走看看