zoukankan      html  css  js  c++  java
  • LeetCode: Tags-[Tree]

    Tags:Tree

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

     中序遍历:

    (解法1:递归; 利用addAll 或者 helper(root,rst);

    解法2: 迭代; 首先cur记录root; while(cur!=null或!stack.empty());1.内部while(cur!=null),则push,cur向左迭代;2.出栈,添值,右;)

    (注意:stack方法-push,pop,peek,empty();  queue方法-offer, poll, peek;)

    ① NLR:前序遍历(PreorderTraversal亦称(先序遍历))——访问根结点的操作发生在遍历其左右子树之前。
    ② LNR:中序遍历(InorderTraversal) ——访问根结点的操作发生在遍历其左右子树之中(间)。
    ③ LRN:后序遍历(PostorderTraversal) ——访问根结点的操作发生在遍历其左右子树之后。
    Recursive解法:
    一个错误解法: (只能遍历出根节点就return了,为什么不是左子树?dont know)
    1 public class Solution {
    2     public List<Integer> inorderTraversal(TreeNode root) {
    3         List<Integer> rst = new ArrayList<>();
    4         if (root.left != null) rst.add(inorderTraversal(root.left));
    5         rst.add(root.val);
    6         if (root.right != null) rst.add(inorderTraversal(root.right));
    7         return rst;
    8     }
    9 }
    View Code

    解法1:利用Java方法addAll(List<>);

     1 public class Solution {
     2     public List<Integer> inorderTraversal(TreeNode root) {
     3         List<Integer> rst = new ArrayList<>();
     4         if (root == null) return rst;
     5         if (root.left != null) rst.addAll(inorderTraversal(root.left));
     6         rst.add(root.val);
     7         if (root.right != null) rst.addAll(inorderTraversal(root.right));
     8         return rst;
     9     }
    10 }
    View Code

    解法2:helper()

    (1.helper-null,left,add,right;  2.inorderTraversal-rst,helper,return;)

     1 public class Solution {
     2     public List<Integer> inorderTraversal(TreeNode root) {
     3         List<Integer> rst = new ArrayList<>();
     4         helper(root, rst);
     5         return rst;
     6     }
     7     public void helper(TreeNode root, List<Integer> rst) {
     8         if (root == null) return;
     9         helper(root.left, rst);
    10         rst.add(root.val);
    11         helper(root.right, rst);
    12     }
    13 }
    View Code

    Iterative解法:<Stack>(4-2-6-1-3-5-null, 当cur!=null时, cur=cur.left遍历左子树, push; 当cur为null时跳出内while循环, 此时cur对于1的左子结点即null, stack里为1,2,4; pop1,cur=1; 接着cur=cur.right; 即已经pop和add了左节点和根节点, 再add右结点, 继续外循环, 如果cur=null, 仍然不执行内循环, 继续pop父节点2, right; 直到empty, 终止循环。所以外循环需要两个判断条件-cur=null或stack.empty)

     (1.rst,stack,cur;  2.while(||) while()-push,left; pop,add,right;  3.return)

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

     

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

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

    (注意出栈后记为cur,入栈是cur的left和right;别总写错成root)

    Recursive:

     1 public class Solution {
     2     public List<Integer> preorderTraversal(TreeNode root) {
     3         List<Integer> rst = new ArrayList<>();
     4         helper(root, rst);
     5         return rst;
     6     }
     7     public void helper(TreeNode root, List<Integer> rst) {
     8         if (root == null) return;
     9         rst.add(root.val);
    10         helper(root.left, rst);
    11         helper(root.right, rst);
    12     }
    13 }
    View Code

    Iterative:(初始stack放入root, cur=root, 每轮循环,pop出一个节点, 然后先push右节点, 再push左节点; 这样每次都add了左节点并且右节点一直在stack中记录着)

    (1.rst,stack,if,push;  2.while(empty) cur,add,if-left,if-right;  3.return)

     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

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

    后序遍历:

    解法1:(pre-NLR, post-LRN, 两种方法:一是先得到NRL再reverse,二是利用LinkedList.addFirst直接得到LRN)

     1 public class Solution {
     2     public List<Integer> postorderTraversal(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.left != null) stack.push(cur.left);
    11             if (cur.right != null) stack.push(cur.right);
    12         }
    13         Collections.reverse(rst);
    14         return rst;
    15     }
    16 }
    View Code
     1 public class Solution {
     2     public List<Integer> postorderTraversal(TreeNode root) {
     3         LinkedList<Integer> rst = new LinkedList<>();
     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.addFirst(cur.val);
    10             if (cur.left != null) stack.push(cur.left);
    11             if (cur.right != null) stack.push(cur.right);
    12         }
    13         return rst;
    14     }
    15 }
    View Code
     1 public List<Integer> postorderTraversal(TreeNode root) {
     2     List<Integer> list = new ArrayList<>();
     3     if(root == null) return list;
     4     Stack<TreeNode> stack = new Stack<>();
     5     stack.push(root);
     6     while(!stack.empty()){
     7         root = stack.pop();
     8         list.add(0, root.val);
     9         if(root.left != null) stack.push(root.left);
    10         if(root.right != null) stack.push(root.right);
    11     }
    12     return list;
    13 }
    View Code

    解法2:(使用pre记录路径, 分三种情况,第一种:如果pre=null或者pre.left/right=cur, 那么是往下遍历, push左树(push完所有左节点), 再push右树; 第二种情况:cur.left=pre, 那么说明是从左树往上遍历, push右树; 第三种情况:可能出现prev=cur或者cur.right=pre, 说明已经到左尾节点或者从右树往上遍历,所以需要add和pop;  总的还是先push左根节点,再在每一个左节点上操作--如果往下遍历则遍历右节点,如果往上遍历则add;)

     1 public ArrayList<Integer> postorderTraversal(TreeNode root) {
     2     ArrayList<Integer> result = new ArrayList<Integer>();
     3     Stack<TreeNode> stack = new Stack<TreeNode>();
     4     TreeNode prev = null; // previously traversed node
     5     TreeNode curr = root;
     6 
     7     if (root == null) {
     8         return result;
     9     }
    10 
    11     stack.push(root);
    12     while (!stack.empty()) {
    13         curr = stack.peek();
    14         if (prev == null || prev.left == curr || prev.right == curr) { // traverse down the tree
    15             if (curr.left != null) {
    16                 stack.push(curr.left);
    17             } else if (curr.right != null) {
    18                 stack.push(curr.right);
    19             }
    20         } else if (curr.left == prev) { // traverse up the tree from the left
    21             if (curr.right != null) {
    22                 stack.push(curr.right);
    23             }
    24         } else { // traverse up the tree from the right
    25             result.add(curr.val);
    26             stack.pop();
    27         }
    28         prev = curr;
    29     }
    30 
    31     return result;
    32 }
    View Code

    95. Unique Binary Search Trees II:https://leetcode.com/problems/unique-binary-search-trees-ii/

    生成所有1-n的二叉树:

    解法:<Recursive>(对于1-n的数,选择i作为根节点,那么左子树是所有1到i-1的树,右子树是所有i+1到n的树,可以用递归求解。例如1-3,当root=1时,左子树1-0,null,右子树为2-3的两种情况;root=2时,左子树为1-1,右子树为2-2;root=3时,左子树1-2,右子树4-3null;所以可以归纳当start>end的时候为null,start=end的时候可以归并到start<end的左右子树情况。即分别遍历左右子树)

    (1.helper(1,n);  2.rst,if(>)null,return;  3.for(start,end),left,right;  4.for(l)for(r)root,left,right,add;  5.return rst;)

     1 public class Solution {
     2     public List<TreeNode> generateTrees(int n) {
     3         if (n == 0) return new ArrayList<TreeNode>();
     4         return helper(1,n);
     5     }
     6     public List<TreeNode> helper(int start, int end){
     7         List<TreeNode> rst = new ArrayList<>();
     8         if (start > end) {
     9             rst.add(null);
    10             return rst;
    11         }
    12 
    13         for (int i = start; i <= end; i++) {
    14             List<TreeNode> left = helper(start, i - 1);
    15             List<TreeNode> right = helper(i + 1, end);
    16             for (TreeNode l : left) { 
    17                 for (TreeNode r : right) {
    18                     TreeNode root = new TreeNode(i);
    19                     root.left = l;
    20                     root.right = r;
    21                     rst.add(root);
    22                 }
    23             }
    24         }
    25         return rst;
    26     }
    27 }
    View Code

    96. Unique Binary Search Trees:https://leetcode.com/problems/unique-binary-search-trees/

    1-n的二叉树的个数:

    我的Recursive解法: (1-18可以pass, 大于19就TLE了)

     1 public class Solution {
     2     public int numTrees(int n) {
     3         if (n == 0 || n == 1) return 1;
     4         int rst = 0;
     5         for (int i = 0; i < n; i++) {
     6             rst = rst + numTrees(n - i - 1) * numTrees(i) ;
     7         }
     8         return rst;
     9     }
    10 }
    View Code

    改进:(将数都保存到数组里, 两次for循环。思想是相同的,都是找出n的规律。G(n) = G(0) * G(n-1) + G(1) * G(n-2) + … + G(n-1) * G(0))

    (1.int[n+1],[0],[1];  2.for(2,n)for(0,i),[i]+=[j]*[i-j-1];  3.return)

     1 public class Solution {
     2     public int numTrees(int n) {
     3         int[] rst = new int[n + 1];
     4         rst[0] = rst[1] = 1;
     5         for (int i = 2; i <= n; i++) {
     6             for (int j = 0; j < i; j++) {
     7                 rst[i] += rst[j] * rst[i - j - 1];
     8             }
     9         }
    10         return rst[n];
    11     }
    12 }
    View Code

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

    验证二叉树:

    解法1:(中序遍历思想,Inorder遍历出来的顺序就是升序的, 使用pre记录前一个数, 如果>=cur则错误)

    (1.stack,cur,pre;  2.while(||) while()push,left;  3.pop,if(&&)-false, pre,left;  4.return true)

     1 public class Solution {
     2     public boolean isValidBST(TreeNode root) {
     3         Stack<TreeNode> stack = new Stack<>();
     4         TreeNode cur = root;
     5         TreeNode pre = null;
     6         while (cur != null || !stack.empty()) {
     7             while (cur != null) {
     8                 stack.push(cur);
     9                 cur = cur.left;
    10             }
    11             cur = stack.pop();
    12             if (pre != null && pre.val >= cur.val) return false;
    13             pre = cur;
    14             cur = cur.right;
    15         }
    16         return true;
    17     }
    18 }
    View Code

    解法2:(Recursive, 每一个node判断是否处于其范围内,及左节点小于父节点的值,又节点大于父节点的值)

    (1.helper(,MAX,MIN);  2.helper: null; if(||); return&&;)

     1 public class Solution {
     2     public boolean isValidBST(TreeNode root) {
     3         return helper(root, Long.MIN_VALUE, Long.MAX_VALUE);
     4     }
     5     public boolean helper(TreeNode root, long lo, long hi) {
     6         if (root == null) return true;
     7         if (root.val >= hi || root.val <= lo) return false;
     8         return helper(root.left, lo, root.val) && helper(root.right, root.val, hi);
     9     }
    10 }
    View Code

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

    判断两树是否相同:

    Recursive解法:

    (1.&null;  2.if(!=null & val),return left&right;  3.return false)

    1 public class Solution {
    2     public boolean isSameTree(TreeNode p, TreeNode q) {
    3         if (p == null && q == null) return true;
    4         if (p != null && q !=null && p.val == q.val)
    5             return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    6         return false;
    7     }
    8 }
    View Code

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

    对称树:

    解法1:Recursive

    (1.null,helper();  2.helper: if(||)return==,  if(val)-false,  return&&)

     1 public class Solution {
     2     public boolean isSymmetric(TreeNode root) {
     3         if (root == null) return true;
     4         return helper(root.left, root.right);
     5     }
     6     public boolean helper(TreeNode left, TreeNode right) {
     7         if (left == null || right == null) return left == right;
     8         if (left.val != right.val) return false;
     9         return helper(left.left, right.right) && helper(left.right, right.left);
    10     }
    11 }
    View Code

    解法2:Iterative(Stack. 例:1,2,2,3,4,4,3; 先push进root.left/right; 判断都为null-continue, 其中一个null或者值不等-false; 然后push进左右节点的四个子节点,在栈中的顺序依次是右左右左4433; 此时pop出两个4,不在判断语句范围内, push进4的left/right即为4个null,此时栈中null*4+33, pop出4个null都continue了,再继续判断33; 满足就return false; 关键点是stack可以push进null, 而且null被pop出后不会有影响。每次pop出最后一个叶节点后就会push进它的null子节点, 算是终止标志了。)

    (1.if,stack,push;  2.while(),n1,n2;  3.if(&&)continue;  4.if(null||val)false;  5.push*4l;  6.return true)

     1 public class Solution {
     2     public boolean isSymmetric(TreeNode root) {
     3         if (root == null) return true;
     4         Stack<TreeNode> stack = new Stack<>();
     5         stack.push(root.left);
     6         stack.push(root.right);
     7         while (!stack.empty()) {
     8             TreeNode n1 = stack.pop(), n2 = stack.pop();
     9             if (n1 == null && n2 == null) continue;
    10             if (n1 == null || n2 == null || n1.val != n2.val) return false;
    11             stack.push(n1.right);
    12             stack.push(n2.left);
    13             stack.push(n1.left);
    14             stack.push(n2.right);
    15         }
    16         return true;
    17     }
    18 }
    View Code
     1 Home   OJ   Symmetric Tree   Recursive and non-recursive solutions in Java 
     2 New users please read the instructions to format your code properly. Discuss is a place to post interview questions or share solutions / ask questions related to OJ problems.
     3 Recursive and non-recursive solutions in Java
     4 
     5 159
     6 L lvlolitte 
     7 Reputation:  506
     8 Recursive--400ms:
     9 
    10 public boolean isSymmetric(TreeNode root) {
    11     return root==null || isSymmetricHelp(root.left, root.right);
    12 }
    13 
    14 private boolean isSymmetricHelp(TreeNode left, TreeNode right){
    15     if(left==null || right==null)
    16         return left==right;
    17     if(left.val!=right.val)
    18         return false;
    19     return isSymmetricHelp(left.left, right.right) && isSymmetricHelp(left.right, right.left);
    20 }
    21 Non-recursive(use Stack)--460ms:
    22 
    23 public boolean isSymmetric(TreeNode root) {
    24     if(root==null)  return true;
    25     
    26     Stack<TreeNode> stack = new Stack<TreeNode>();
    27     TreeNode left, right;
    28     if(root.left!=null){
    29         if(root.right==null) return false;
    30         stack.push(root.left);
    31         stack.push(root.right);
    32     }
    33     else if(root.right!=null){
    34         return false;
    35     }
    36         
    37     while(!stack.empty()){
    38         if(stack.size()%2!=0)   return false;
    39         right = stack.pop();
    40         left = stack.pop();
    41         if(right.val!=left.val) return false;
    42         
    43         if(left.left!=null){
    44             if(right.right==null)   return false;
    45             stack.push(left.left);
    46             stack.push(right.right);
    47         }
    48         else if(right.right!=null){
    49             return false;
    50         }
    51             
    52         if(left.right!=null){
    53             if(right.left==null)   return false;
    54             stack.push(left.right);
    55             stack.push(right.left);
    56         }
    57         else if(right.left!=null){
    58             return false;
    59         }
    60     }
    61     
    62     return true;
    63 }
    View Code

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

    层序遍历:

    解法1:<BFS> <Queue>(for循环遍历每层节点,左右节点不为null则offer进queue;每趟循环poll出该层节点add进list里。ps:queue是接口,不能实例化,只能通过已经存在的实现比如LinkedList。Stack有方法empty(); queue的LinkedList继承了List的isEmpty()方法;)

    (1.queue,rst,if(),offer;  2.while(),list,size;  3.for(),poll,list,if()-offer, rst  4.return)

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

    解法2: <DFS> <Recursive>(定义helper(rst,root,heght), rst.get(height).add(rot.val), 递归)

     1 public List<List<Integer>> levelOrder(TreeNode root) {
     2         List<List<Integer>> res = new ArrayList<List<Integer>>();
     3         levelHelper(res, root, 0);
     4         return res;
     5     }
     6     
     7     public void levelHelper(List<List<Integer>> res, TreeNode root, int height) {
     8         if (root == null) return;
     9         if (height >= res.size()) {
    10             res.add(new LinkedList<Integer>());
    11         }
    12         res.get(height).add(root.val);
    13         levelHelper(res, root.left, height+1);
    14         levelHelper(res, root.right, height+1);
    15     }
    View Code

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

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

    我的解法:<BFS>(和层序遍历方法相同。增加了count作为计数。count=1的时候add(val),然后count置零。else-add(0,val),count-1;)

    (1.rst,queue,null,offer,count;  2.while(),size,list;  3.if(1)for(),node,add,offer,0;  4.if(0),add(0,val);  5.rst.add;return)

     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         int count = 1;
     8         while (!queue.isEmpty()) {
     9             int size = queue.size();
    10             List<Integer> list = new LinkedList<>();
    11             if (count == 1) {
    12                 for (int i = 0; i < size; i++) {
    13                     TreeNode node = queue.poll();
    14                     list.add(node.val);
    15                     if (node.left != null) queue.offer(node.left);
    16                     if (node.right != null) queue.offer(node.right);
    17                 }
    18                 count = 0;
    19             } else {
    20                 for (int i = 0; i < size; i++) {
    21                     TreeNode node = queue.poll();
    22                     list.add(0, node.val);
    23                     if (node.left != null) queue.offer(node.left);
    24                     if (node.right != null) queue.offer(node.right);
    25                 }
    26                 count = 1;
    27             }
    28             rst.add(list);
    29         }
    30         return rst;
    31     }
    32 }
    View Code

    改进:(1.rst,queue,null,offer,order;  2.while(),size,list;  3.for(),node,if-add,else-add(0),offer;  4.order,rst;return;)

     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

    解法2:<DFS>

     1 public class Solution {
     2     public List<List<Integer>> zigzagLevelOrder(TreeNode root) 
     3     {
     4         List<List<Integer>> sol = new ArrayList<>();
     5         travel(root, sol, 0);
     6         return sol;
     7     }
     8     
     9     private void travel(TreeNode curr, List<List<Integer>> sol, int level)
    10     {
    11         if(curr == null) return;
    12         
    13         if(sol.size() <= level)
    14         {
    15             List<Integer> newLevel = new LinkedList<>();
    16             sol.add(newLevel);
    17         }
    18         
    19         List<Integer> collection  = sol.get(level);
    20         if(level % 2 == 0) collection.add(curr.val);
    21         else collection.add(0, curr.val);
    22         
    23         travel(curr.left, sol, level + 1);
    24         travel(curr.right, sol, level + 1);
    25     }
    26 }
    View Code

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

    最大深度:

    我的解法:<Recursive><Greedy>

    (1.null,0;  2.rst,Math.max;  3.return rst+1)

    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:<BFS>(Level Order Traverse思想)

     1 public int maxDepth(TreeNode root) {
     2     if(root == null) {
     3         return 0;
     4     }
     5     Queue<TreeNode> queue = new LinkedList<>();
     6     queue.offer(root);
     7     int count = 0;
     8     while(!queue.isEmpty()) {
     9         int size = queue.size();
    10         while(size-- > 0) {
    11             TreeNode node = queue.poll();
    12             if(node.left != null) {
    13                 queue.offer(node.left);
    14             }
    15             if(node.right != null) {
    16                 queue.offer(node.right);
    17             }
    18         }
    19         count++;
    20     }
    21     return count;
    22 }
    View Code

    107. 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)的方法)

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

    解法2:DFS

     1 public class Solution {
     2         public List<List<Integer>> levelOrderBottom(TreeNode root) {
     3             List<List<Integer>> wrapList = new LinkedList<List<Integer>>();
     4             levelMaker(wrapList, root, 0);
     5             return wrapList;
     6         }
     7         
     8         public void levelMaker(List<List<Integer>> list, TreeNode root, int level) {
     9             if(root == null) return;
    10             if(level >= list.size()) {
    11                 list.add(0, new LinkedList<Integer>());
    12             }
    13             levelMaker(list, root.left, level+1);
    14             levelMaker(list, root.right, level+1);
    15             list.get(list.size()-level-1).add(root.val);
    16         }
    17     }
    View Code

    110. 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)

     1 public class Solution {
     2     public boolean isBalanced(TreeNode root) {
     3         if (root == null) return true;
     4         int rst = Math.abs(depth(root.left) - depth(root.right));
     5         return (rst <= 1) && isBalanced(root.left) && isBalanced(root.right);
     6     }
     7     public int depth(TreeNode root) {
     8         if (root == null) return 0;
     9         int rst = Math.max(depth(root.left), depth(root.right));
    10         return rst + 1;
    11     }
    12 }
    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;)

     1 public class Solution {
     2     public boolean isBalanced(TreeNode root) {
     3         return height(root) != -1;
     4     }
     5     public int height(TreeNode root) {
     6         if (root == null) return 0;
     7         int lh = height(root.left);
     8         if (lh == -1) return -1;
     9         int rh = height(root.right);
    10         if (rh == -1) return -1;
    11         if (Math.abs(lh - rh) > 1) return -1;
    12         return Math.max(lh, rh) + 1;
    13     }
    14 }
    View Code

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

    最小深度:

    我的解法:<Recursive><DFS>(和maxDepth相比,一个特殊点就是当left为null的时候而right不为null时,需要继续遍历right,选择叶节点作为终点——即左右节点都不为null。所以可以添加语句:left==null,则返回min(right)+1; 例如:[1,null,3,4]-return3; [1,null,3,4,5,6]-return3;)

    (1.root,left,right;  2.rst,return)

    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: <BFS><Level Order Traverse>(层序遍历思想。和maxDepth的区别是,遇到left和right都为null的时候就return count;而有不为null的则继续遍历cnt++)

    (1.root,queue,offer,count1; 2.while()size,poll; 3.for()node,if(&&)count,if(!=); 4.count++,return)

     1 public class Solution {
     2     public int minDepth(TreeNode root) {
     3         if (root == null) return 0;
     4         Queue<TreeNode> queue = new LinkedList<>();
     5         queue.offer(root);
     6         int count = 1;
     7         while (!queue.isEmpty()) {
     8             int size = queue.size();
     9             for (int i = 0; i < size; i++) {
    10                 TreeNode node = queue.poll();
    11                 if (node.left == null && node.right == null) return count;
    12                 if (node.left != null) queue.offer(node.left);
    13                 if (node.right != null) queue.offer(node.right);
    14             }
    15             count++;
    16         }
    17         return count;
    18     }
    19 }
    View Code

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

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

    我的解法:<Recursive>(1-2-3-null-4,sum=7为例; root==null的时候是判false的,刚开始我是return sum==0;其实不可以。首先1,左右节点都不为null,递归到2和3;2-6,3-6,对与2,左节点为null,右节点为4,因为它的左右节点没有都为null,所以它不是叶节点,要继续递归!对于3,已经是页节点,return 3==6; 2继续递归,左节点为null,return false!而不是return sum = 0的!因为只有当子节点有一个为null的时候才会存在判断null的情况,那么它不是叶节点,return false,利用val=sum判断另一个节点是否符合。注意:节点值和sum值都是可负的,不要多此一举添加sum<0的判断.PS:leetcode的testcase也很迷,第一次提交beat9%,第二次提交beat99%……)

    (1.if(null); 2.if(&&)=; 3.return&&;)

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

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

    返回路径值:

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

    (1.rst,list,helper,return;  2.helper: if(root);  3.if(left,right);if(=)-add,add,remove;return 4.add,helper,remove)

     1 public class Solution {
     2     public List<List<Integer>> pathSum(TreeNode root, int sum) {
     3         List<List<Integer>> rst = new ArrayList<>();
     4         List<Integer> list = new ArrayList<>();
     5         helper(root, sum, list, rst);
     6         return rst;
     7     }
     8     public void helper(TreeNode root, int sum, List<Integer> list, List<List<Integer>> rst) {
     9         if (root == null) return;
    10         if (root.left == null && root.right == null) {
    11             if (root.val == sum) {
    12                 list.add(root.val);
    13                 rst.add(new ArrayList<Integer>(list));
    14                 list.remove(list.size() - 1);
    15             }
    16             return;
    17         }
    18         list.add(root.val);
    19         helper(root.left, sum - root.val, list, rst);
    20         helper(root.right, sum - root.val, list, rst);
    21         list.remove(list.size() - 1);
    22     }
    23 }
    View Code

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

    反转二叉树:

    我的解法:<Recursive>(利用tmp和常规swap方法+Recursive。需要root==null的判断情况。例如:[4,2,7,1,null,null,9])

    (1.heler;  2.helper:if(root);  3.tmp,left,right;  4.return root)

     1 public class Solution {
     2     public TreeNode invertTree(TreeNode root) {
     3         return helper(root);
     4     }
     5     public TreeNode helper(TreeNode root) {
     6         if (root == null) return root;
     7         TreeNode tmp = helper(root.right);
     8         root.right = helper(root.left);
     9         root.left = tmp;
    10         return root;
    11     }
    12 }
    View Code
    1 public TreeNode invertTree(TreeNode root) {
    2         if (root == null) return null;
    3         TreeNode tempRight = root.right;
    4         root.right = invertTree(root.left);
    5         root.left = invertTree(tempRight);
    6         return root;
    7     }
    View Code

    上面解法是从下往上swap,也可以从上往下:

     1 public class Solution {
     2     public TreeNode invertTree(TreeNode root) {
     3         
     4         if (root == null) {
     5             return null;
     6         }
     7 
     8         final TreeNode left = root.left,
     9                 right = root.right;
    10         root.left = invertTree(right);
    11         root.right = invertTree(left);
    12         return root;
    13     }
    14 }
    View Code

    解法2:<Iterative>(Level Order层序遍历思想,从上往下的方法改为用栈来实现。)

    (1.if,queue,offer;  2.while,poll,swap;  3.if-offer;  4.return)

     1 public class Solution {
     2     public TreeNode invertTree(TreeNode root) {
     3         if (root == null) return null;
     4         Queue<TreeNode> queue = new LinkedList<>();
     5         queue.offer(root);
     6         while (!queue.isEmpty()) {
     7             TreeNode node = queue.poll();
     8             //swap;
     9             TreeNode tmp = node.right;
    10             node.right = node.left;
    11             node.left = tmp;
    12             //offer;
    13             if (node.left != null) queue.offer(node.left);
    14             if (node.right != null) queue.offer(node.right);
    15         }
    16         return root;
    17     }
    18 }
    View Code

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

    BST-两个节点的最低的同祖先节点:

    解法:(利用二叉搜索树BST性质--左子树小于root,右子树大于root;往下遍历确保两个节点在同一子树。else情况包括分别大于和小于root;或者其中一个等于root。PS:二叉树只是普通的左右指针树,二叉搜索数才有大小性质)

    Recursive:

     1 public class Solution {
     2     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
     3         if(root.val > p.val && root.val > q.val){
     4             return lowestCommonAncestor(root.left, p, q);
     5         }else if(root.val < p.val && root.val < q.val){
     6             return lowestCommonAncestor(root.right, p, q);
     7         }else{
     8             return root;
     9         }
    10     }
    11 }
    View Code

    Non-Recursive:

    (1.while(true);  2.if(<)left, elseif(>)right,else-break;  3.return)

     1 public class Solution {
     2     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
     3         while (true) {
     4             if (p.val < root.val && q.val < root.val) root = root.left;
     5             else if (p.val > root.val && q.val > root.val) root = root.right;
     6             else break;
     7         }
     8         return root;
     9     }
    10 }
    View Code
     1 public class Solution {
     2     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
     3         while (true) {
     4             if (root.val > p.val && root.val > q.val)
     5                 root = root.left;
     6             else if (root.val < p.val && root.val < q.val)
     7                 root = root.right;
     8             else
     9                 return root;
    10         }
    11     }
    12 }
    View Code

    257. Binary Tree Paths:https://leetcode.com/problems/binary-tree-paths/

    二叉树的所有路径(路径为字符串):

    解法1:<Recursive>(helper,终止条件是:叶节点。)

    (1.rst,if(!=),helper; 2.helper: if(&&)add, if(!=)helper)

     1 public class Solution {
     2     public List<String> binaryTreePaths(TreeNode root) {
     3         List<String> rst = new ArrayList<>();
     4         if(root != null) helper(root, "", rst);
     5         return rst;
     6     }
     7     public void helper(TreeNode root, String str, List<String> rst) {
     8         if (root.left == null && root.right == null) rst.add(str + root.val);
     9         if (root.left != null) helper(root.left, str + root.val + "->", rst);
    10         if (root.right != null) helper(root.right, str + root.val + "->", rst);
    11     }
    12 }
    View Code

    404. Sum of Left Leaves: https://leetcode.com/problems/sum-of-left-leaves/

    所有左叶节点的和:

    解法1:<Recursive>(左节点不为null,如果为叶则add,否则递归;右节点不为null,递归。 刚开始用helper(root,sum)做,结果不正确,好像是被重复加了)

    (1.if,sum;  2.if(left),if(&&)-val,else-Rec;  3.if(right)-Rec;  4.return)

     1 public class Solution {
     2     public int sumOfLeftLeaves(TreeNode root) {
     3         if (root == null) return 0;
     4         int sum = 0;
     5         if (root.left != null) {
     6             if (root.left.left == null && root.left.right == null) {
     7                 sum += root.left.val;
     8             } else {
     9                 sum += sumOfLeftLeaves(root.left);
    10             }
    11         }
    12         if (root.right != null) {
    13             sum += sumOfLeftLeaves(root.right);
    14         }
    15         return sum;
    16     }
    17 }
    View Code
     1 public int sumOfLeftLeaves(TreeNode root) {
     2     if(root == null) return 0;
     3     int ans = 0;
     4     if(root.left != null) {
     5         if(root.left.left == null && root.left.right == null) ans += root.left.val;
     6         else ans += sumOfLeftLeaves(root.left);
     7     }
     8     ans += sumOfLeftLeaves(root.right);
     9     
    10     return ans;
    11 }
    View Code

    解法2:<Iterative>

     1 public int sumOfLeftLeaves(TreeNode root) {
     2     if(root == null) return 0;
     3     int ans = 0;
     4     Stack<TreeNode> stack = new Stack<TreeNode>();
     5     stack.push(root);
     6     
     7     while(!stack.empty()) {
     8         TreeNode node = stack.pop();
     9         if(node.left != null) {
    10             if (node.left.left == null && node.left.right == null)
    11                 ans += node.left.val;
    12             else
    13                 stack.push(node.left);
    14         }
    15         if(node.right != null) {
    16             if (node.right.left != null || node.right.right != null)
    17                 stack.push(node.right);
    18         }
    19     }
    20     return ans;
    21 }
    View Code

    437. Path Sum III: https://leetcode.com/problems/path-sum-iii/

  • 相关阅读:
    Quick Sort
    Binary Search
    trollcave解题
    Openvas简介
    SMB扫描-Server Message Block 协议、nmap
    漏洞基本概念
    防火墙识别、负载均衡识别、waf识别
    Centos7下部署Python项目
    Python-Redis数据类型操作
    MySQL的事务隔离级别
  • 原文地址:https://www.cnblogs.com/buwenyuwu/p/6298257.html
Copyright © 2011-2022 走看看