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

  • 相关阅读:
    git reset 用法
    print、println、printf的区别
    GoLang(2)
    GoLang
    OpenCV 图像叠加or图像混合加权实现
    openpyxl
    EJB 的理解
    inotify-tool实时监控服务器文件状态变化 学习总结
    使用docker 安装maven私服 nexus
    dockerfile 学习总结
  • 原文地址:https://www.cnblogs.com/buwenyuwu/p/6587887.html
Copyright © 2011-2022 走看看