题目列表
前中后序遍历
- 144. 二叉树的前序遍历
- 94. 二叉树的中序遍历
- 145. 二叉树的后序遍历
-
层序遍历
- 103. 二叉树的锯齿形层序遍历
- 199. 二叉树的右视图
-
构造二叉树
-
DFS
- 113. 路径总和 II
- 112. 路径总和
-
递归+非递归
- 101. 对称二叉树
-
递归流
- 110. 平衡二叉树【自顶向下,自底向上】
- 124. 二叉树中的最大路径和
-
具体代码
前中后序遍历
144. 二叉树的前序遍历
class Solution {public List<Integer> preorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if(root == null) return res;Stack<TreeNode> stk = new Stack<>();TreeNode cur = root;while(!stk.isEmpty() || cur != null){if(cur != null){res.add(cur.val);stk.push(cur);cur = cur.left;}else{TreeNode node = stk.pop();cur = node.right;}}return res;}}
94. 二叉树的中序遍历
class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if(root == null) return res;Stack<TreeNode> stk = new Stack<>();TreeNode cur = root;while(!stk.isEmpty() || cur != null){if(cur != null){stk.add(cur);cur = cur.left;}else{TreeNode node = stk.pop();res.add(node.val);cur = node.right;}}return res;}}
145. 二叉树的后序遍历
还要反转一下,不太行。。。
class Solution {public List<Integer> postorderTraversal(TreeNode root) {List<Integer> res = new ArrayList<>();if(root == null) return res;Stack<TreeNode> stk = new Stack<>();TreeNode cur = root;while(!stk.isEmpty() || cur != null){if(cur != null){res.add(cur.val);stk.push(cur);cur = cur.right;}else{TreeNode node = stk.pop();cur = node.left;}}Collections.reverse(res);return res;}}
剑指 Offer 54. 二叉搜索树的第k大节点
class Solution {public int kthLargest(TreeNode root, int k) {int t = 1;Stack<TreeNode> stk = new Stack<>();TreeNode cur = root;while(!stk.isEmpty() || cur != null){if(cur != null){stk.push(cur);cur = cur.right;}else{TreeNode node = stk.pop();if(t == k) return node.val;t++;cur = node.left;}}return -1;}}
层序遍历
102. 二叉树的层序遍历
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();if(root == null) return res;Queue<TreeNode> q = new LinkedList<>();q.offer(root);while(!q.isEmpty()){int x = q.size();ArrayList<Integer> tmp = new ArrayList<>();for(int i = 0; i < x; i++){TreeNode node = q.poll();tmp.add(node.val);if(node.left != null) q.offer(node.left);if(node.right != null) q.offer(node.right);}res.add(tmp);}return res;}}
103. 二叉树的锯齿形层序遍历
class Solution {public List<List<Integer>> zigzagLevelOrder(TreeNode root) {List<List<Integer>> res = new ArrayList<>();if(root == null) return res;Queue<TreeNode> q = new LinkedList<>();q.offer(root);int level = 1;while(!q.isEmpty()){int x = q.size();ArrayList<Integer> tmp = new ArrayList<>();for(int i = 0; i < x; i++){TreeNode node = q.poll();if(level % 2 != 0){tmp.add(node.val);}else{tmp.add(0, node.val);}if(node.left != null) q.offer(node.left);if(node.right != null) q.offer(node.right);}res.add(tmp);level++;}return res;}}
199. 二叉树的右视图
class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> res = new ArrayList<>();if(root == null) return res;Queue<TreeNode> q = new LinkedList<>();q.offer(root);while(!q.isEmpty()){int x = q.size();for(int i = 0 ; i < x; i++){TreeNode node = q.poll();if(i == x - 1) res.add(node.val);if(node.left != null) q.offer(node.left);if(node.right != null) q.offer(node.right);}}return res;}}
958. 二叉树的完全性检验
class Solution {public boolean isCompleteTree(TreeNode root) {boolean f = false;Queue<TreeNode> q = new LinkedList<>();q.offer(root);while(!q.isEmpty()){TreeNode node = q.poll();if(f == true && node != null) return false;if(node == null){f = true;continue;}q.offer(node.left);q.offer(node.right);}return true;}}
构造二叉树
105. 从前序与中序遍历序列构造二叉树
if(pl > pr) return null; 递归出口不能忘
不能写成 pl >= pr
class Solution {Map<Integer, Integer> map = new HashMap<>();public TreeNode makeTree(int[] pre, int pl, int pr, int[] in, int il, int ir){if(pl > pr) return null;int x = pre[pl];TreeNode root = new TreeNode(x);int k = map.get(x);root.left = makeTree(pre, pl + 1, k - il + pl, in, il, k - 1);root.right = makeTree(pre, k - il + pl + 1, pr, in, k + 1, ir);return root;}public TreeNode buildTree(int[] preorder, int[] inorder) {for(int i = 0; i < inorder.length; i++) map.put(inorder[i], i);return makeTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);}}
DFS
104. 二叉树的最大深度
class Solution {int res = 0;public void dfs(TreeNode root, int d){if(root.left == null && root.right == null) {res = Math.max(res, d);return;}if(root.left != null) dfs(root.left, d + 1);if(root.right != null) dfs(root.right, d + 1);}public int maxDepth(TreeNode root) {if(root == null) return 0;dfs(root, 1);return res;}}
113. 路径总和 II
class Solution {List<List<Integer>> res;public void dfs(TreeNode root, int sum, int targetSum, ArrayList tmp){if(root.left == null && root.right == null){if(sum == targetSum) res.add(new ArrayList(tmp));return;}if(root.left != null){tmp.add(root.left.val);dfs(root.left, sum + root.left.val, targetSum, tmp);tmp.remove(tmp.size() - 1);}if(root.right != null){tmp.add(root.right.val);dfs(root.right, sum + root.right.val, targetSum, tmp);tmp.remove(tmp.size() - 1);}}public List<List<Integer>> pathSum(TreeNode root, int targetSum) {res = new ArrayList<>();if(root == null) return res;ArrayList<Integer> tmp = new ArrayList<>();tmp.add(root.val);dfs(root, root.val, targetSum, tmp);return res;}}
112. 路径总和
class Solution {boolean f = false;public void dfs(TreeNode root, int sum, int targetSum){if(root.left == null && root.right == null){if(sum == targetSum) {f = true;return;}}if(f) return;if(root.left != null) dfs(root.left, sum + root.left.val, targetSum);if(root.right != null) dfs(root.right, sum + root.right.val, targetSum);}public boolean hasPathSum(TreeNode root, int targetSum) {if(root == null) return false;dfs(root, root.val, targetSum);return f;}}
129. 求根节点到叶节点数字之和
class Solution {int res = 0;public void dfs(TreeNode root, int tmp){if(root.left == null && root.right == null){res += tmp;return;}if(root.left != null) dfs(root.left, tmp * 10 + root.left.val);if(root.right != null) dfs(root.right, tmp * 10 + root.right.val);}public int sumNumbers(TreeNode root) {dfs(root, root.val);return res;}}
递归+非递归
226. 翻转二叉树
递归
class Solution {public void reverse(TreeNode root){if(root == null) return;TreeNode tmp = root.left;root.left = root.right;root.right = tmp;reverse(root.left);reverse(root.right);}public TreeNode invertTree(TreeNode root) {reverse(root);return root;}}
非递归
class Solution {public TreeNode invertTree(TreeNode root) {if(root == null) return null;Queue<TreeNode> q = new LinkedList<>();q.offer(root);while(!q.isEmpty()){TreeNode node = q.poll();TreeNode tmp = node.left;node.left = node.right;node.right = tmp;if(node.left != null) q.offer(node.left);if(node.right != null) q.offer(node.right);}return root;}}
101. 对称二叉树
递归
class Solution {public boolean judge(TreeNode l, TreeNode r){if(l == null && r == null) return true;if(l == null || r == null) return false;if(l.val != r.val) return false;return judge(l.left, r.right)&&judge(l.right, r.left);}public boolean isSymmetric(TreeNode root) {if(root == null) return true;return judge(root.left, root.right);}}
非递归
class Solution {public boolean isSymmetric(TreeNode root) {if(root == null) return true;Stack<TreeNode> stk = new Stack<>();stk.push(root.left);stk.push(root.right);while(!stk.isEmpty()){TreeNode l = stk.pop();TreeNode r = stk.pop();if(l == null && r == null) continue;if(l == null || r == null) return false;if(l.val != r.val) return false;stk.push(l.left);stk.push(r.right);stk.push(l.right);stk.push(r.left);}return true;}}
98. 验证二叉搜索树
非递归,中序为升序判断
class Solution {public boolean isValidBST(TreeNode root) {if(root == null) return true;double pre = -Double.MAX_VALUE;Stack<TreeNode> stk = new Stack<>();TreeNode cur = root;while(!stk.isEmpty() || cur != null){if(cur != null){stk.push(cur);cur = cur.left;}else{TreeNode node = stk.pop();if(node.val <= pre) return false;pre = node.val;cur = node.right;}}return true;}}
递归
class Solution {public boolean isValidBST(TreeNode root) {if(root == null) return true;return judge(root, Long.MIN_VALUE, Long.MAX_VALUE);}public boolean judge(TreeNode root, long low, long up){if(root == null) return true;if(root.val <= low || root.val >= up) return false;return judge(root.left, low, root.val)&&judge(root.right, root.val, up);}}
递归流
236. 二叉树的最近公共祖先
class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null || root == p || root == q) return root;TreeNode l = lowestCommonAncestor(root.left, p, q);TreeNode r = lowestCommonAncestor(root.right, p, q);if(l != null && r != null) return root;else if(l != null) return l;else return r;}}
class Solution {/**注意p,q必然存在树内, 且所有节点的值唯一!!!递归思想, 对以root为根的(子)树进行查找p和q, 如果root == null || p || q 直接返回root表示对于当前树的查找已经完毕, 否则对左右子树进行查找, 根据左右子树的返回值判断:1. 左右子树的返回值都不为null, 由于值唯一左右子树的返回值就是p和q, 此时root为LCA2. 如果左右子树返回值只有一个不为null, 说明只有p和q存在与左或右子树中, 最先找到的那个节点为LCA3. 左右子树返回值均为null, p和q均不在树中, 返回null**/public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root == null || root == p || root == q) return root;TreeNode l = lowestCommonAncestor(root.left, p, q);TreeNode r = lowestCommonAncestor(root.right, p, q);if(l != null && r != null) return root;else if(l != null) return l;else if(r != null) return r;else return null;}}
110. 平衡二叉树
自顶向下,有大量重复计算
class Solution {public int getDepth(TreeNode root){if(root == null) return 0;int l = getDepth(root.left);int r = getDepth(root.right);return Math.max(l, r) + 1;}public boolean isBalanced(TreeNode root) {if(root == null) return true;int l = getDepth(root.left);int r = getDepth(root.right);if(Math.abs(l - r) > 1) return false;return isBalanced(root.left)&&isBalanced(root.right);}}
自底向上
class Solution {public boolean isBalanced(TreeNode root) {return judge(root) >= 0;}public int judge(TreeNode root){if(root == null) return 0;int l = judge(root.left);int r = judge(root.right);if(l >= 0 && r >= 0 && Math.abs(l - r) <= 1){return Math.max(l, r) + 1;}else{return -1;}}}
124. 二叉树中的最大路径和
class Solution {int res = Integer.MIN_VALUE;public int getRes(TreeNode root){if(root == null) return 0;int l = Math.max(0, getRes(root.left));int r = Math.max(0, getRes(root.right));res = Math.max(res, l + r + root.val);return Math.max(l, r) + root.val;}public int maxPathSum(TreeNode root) {if(root == null) return 0;getRes(root);return res;}}
543. 二叉树的直径
class Solution { int res = Integer.MIN_VALUE; public int getRes(TreeNode root){ if(root == null) return 0; int l = root.left == null ? 0: getRes(root.left) + 1; int r = root.right == null ? 0: getRes(root.right) + 1; res = Math.max(res, l + r); return Math.max(l, r); } public int diameterOfBinaryTree(TreeNode root) { if(root == null) return 0; getRes(root); return res; } }
