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;)

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 }
解法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 }
解法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 }
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 }
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 }
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 }
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 }

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 }

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 }
解法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 }
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 }
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 }
改进:(将数都保存到数组里, 两次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 }
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 }
解法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 }
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 }
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 }
解法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 }

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 }
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 }
解法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 }
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 }
改进:(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 }
解法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 }
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 }
解法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 }
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 }
解法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 }
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 }
解法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 }
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 }
我的解法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 }
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 }
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 }
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 }

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 }
上面解法是从下往上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 }
解法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 }
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 }
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 }

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 }
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 }
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 }

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 }
解法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 }
437. Path Sum III: https://leetcode.com/problems/path-sum-iii/