复习
深度优先遍历
前序遍历
https://leetcode.com/problems/binary-tree-preorder-traversal/description/
递归法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
preorder(root, result);
return result; }
public void preorder(TreeNode root, List<Integer> result){ if (root == null) return;
result.add(root.val); preorder(root.left, result); preorder(root.right, result); } }
|
迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){ TreeNode node = stack.pop(); result.add(node.val); if (node.right != null) stack.push(node.right); if (node.left != null) stack.push(node.left); }
return result; } }
|
统一迭代法
node设置的时候,要注意弹出之后的下一个值才是重点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root); while (!stack.isEmpty()){ TreeNode node = stack.peek(); if (node != null){ stack.pop(); if (node.right != null) stack.push(node.right); if (node.left != null) stack.push(node.left); stack.push(node); stack.push(null); } else { stack.pop(); result.add(stack.pop().val); } }
return result; } }
|
后序遍历
https://leetcode.com/problems/binary-tree-postorder-traversal/description/
递归法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
postorder(root, result);
return result; }
public void postorder(TreeNode root, List<Integer> result){ if (root == null) return; postorder(root.left, result); postorder(root.right, result); result.add(root.val); } }
|
####迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root); while (!stack.isEmpty()){ TreeNode node = stack.pop();
result.add(node.val); if (node.left != null) stack.push(node.left); if (node.right != null) stack.push(node.right); }
Collections.reverse(result);
return result; } }
|
####统一迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root); while (!stack.isEmpty()){ TreeNode node = stack.pop(); if (node != null){ stack.push(node); stack.push(null); if (node.right != null) stack.push(node.right); if (node.left != null) stack.push(node.left); } else { result.add(stack.pop().val); } }
return result; } }
|
中序遍历
https://leetcode.com/problems/binary-tree-inorder-traversal/description/
递归法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
inorder(root, result);
return result; }
public void inorder(TreeNode root, List<Integer> result){ if (root == null) return;
inorder(root.left, result); result.add(root.val); inorder(root.right, result); } }
|
迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()){ if (cur != null){ stack.push(cur); cur = cur.left; } else { cur = stack.pop(); result.add(cur.val); cur = cur.right; } } return result; } }
|
统一迭代法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>();
if (root == null) return result;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()){ TreeNode node = stack.pop(); if (node != null){ if (node.right != null) stack.push(node.right); stack.push(node); stack.push(null); if (node.left != null) stack.push(node.left); } else { result.add(stack.pop().val); } }
return result; } }
|
广度优先遍历 层序遍历
https://leetcode.com/problems/binary-tree-level-order-traversal/description/
DFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); dfs(root, 0, result); return result; }
public void dfs(TreeNode root, int depth, List<List<Integer>> result){ if (root == null) return;
depth++;
if (result.size() < depth){ List<Integer> itemList = new ArrayList<>(); result.add(itemList); }
result.get(depth - 1).add(root.val);
dfs(root.left, depth, result); dfs(root.right, depth, result); } }
|
BFS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public List<List<Integer>> levelOrder(TreeNode root) { List<List<Integer>> result = new ArrayList<>(); bfs(root, result);
return result; }
public void bfs(TreeNode root, List<List<Integer>> result){ if (root == null) return;
Queue<TreeNode> queue = new ArrayDeque<>(); queue.add(root);
while (!queue.isEmpty()){ List<Integer> itemList = new ArrayList<>(); int length = queue.size(); while (length-- > 0){ TreeNode node = queue.poll(); itemList.add(node.val); if (node.left != null ) queue.add(node.left); if (node.right != null) queue.add(node.right); }
result.add(itemList); } } }
|
104 二叉树的最大深度
https://leetcode.com/problems/maximum-depth-of-binary-tree/description/
二叉树的深度,指根节点到该节点的最长简单路径边的条数或者节点数
二叉树的高度,指该节点到叶子结点的最长简单路径边的条数或者节点数
而根节点的高度就是二叉树的最大深度
使用前序遍历求的是深度,使用后序遍历求的是高度
此题可通过后序遍历求根节点的高度
depth 每次递归更新加一和最大深度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution { public int maxDepth(TreeNode root) { return getDepth(root); } public int getDepth(TreeNode root){ if (root == null) return 0;
int leftDepth = getDepth(root.left); int rightDepth = getDepth(root.right); int depth = 1 + Math.max(leftDepth, rightDepth);
return depth; } }
|
精简
1 2 3 4 5 6
| class Solution { public int maxDepth(TreeNode root){ if (root == null) return 0; return 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); } }
|
迭代法可通过层序遍历bfs拿到depth
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public int maxDepth(TreeNode root) { return bfs(root); }
public int bfs(TreeNode root){ if (root == null) return 0; Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root); int depth = 0; while (!queue.isEmpty()){ int length = queue.size();
while (length-- > 0){
TreeNode node = queue.poll(); if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); }
depth++; }
return depth; } }
|
559 n叉树的最大深度
层序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int maxDepth(Node root) { if (root == null) return 0;
Queue<Node> queue = new ArrayDeque<>();
int depth = 0; queue.add(root); while (!queue.isEmpty()){ int length = queue.size();
while (length-- > 0){ Node node = queue.poll(); if (!node.children.isEmpty()){ for (Node i : node.children){ queue.add(i); } } } depth++; } return depth; } }
|
递归法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public int maxDepth(Node root) { return getDepth(root); }
public int getDepth(Node root){ if (root == null) return 0; int depth = 0; if (!root.children.isEmpty()){ for (Node i : root.children){ depth = Math.max(getDepth(i), depth); } } return depth + 1; } }
|
111 二叉树的最小深度
层序遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int minDepth(TreeNode root) { if (root == null) return 0;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root); int depth = 0; while (!queue.isEmpty()){ depth++; int length = queue.size(); while (length-- > 0){ TreeNode node = queue.poll();
if (node.left == null && node.right == null){ return depth; } if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } }
return depth; } }
|
递归法
要确定左子树和右子树的情况
和最大深度不同,最大深度,max可以不考虑左子树和右子树的情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int minDepth(TreeNode root) { if (root == null) return 0;
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
if (root.left == null && root.right != null){ return 1 + rightDepth; }
if (root.left != null && root.right == null){ return 1 + leftDepth; }
int depth = 1 + Math.min(leftDepth, rightDepth); return depth; } }
|
222 完全二叉树的节点个数
普通二叉树数节点数量
利用后序遍历递归,求数量
1 2 3 4 5 6 7 8 9 10 11 12
| class Solution { public int countNodes(TreeNode root) { if (root == null) return 0; int leftNum = countNodes(root.left); int rightNum = countNodes(root.right); int num = leftNum + rightNum + 1;
return num; } }
|
利用层序遍历统计数量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Solution { public int countNodes(TreeNode root) { if (root == null) return 0;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root); int sum = 0; while (!queue.isEmpty()){ int length = queue.size(); sum += length;
while (length-- > 0){ TreeNode node = queue.poll();
if (node.left != null) queue.add(node.left); if (node.right != null) queue.add(node.right); } }
return sum; } }
|
利用完全二叉树的特性
因为除了最底层没填满外,其他的结点都是满的
如果向左递归的深度,不等于向右递归的深度,则说明不是满二叉树
满二叉树节点为2^depth - 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public int countNodes(TreeNode root) { if (root == null) return 0; TreeNode left = root.left;
TreeNode right = root.right;
int leftDepth = 0; int rightDepth = 0;
while (left != null){ left = left.left; leftDepth++; } while (right != null){ right = right.right; rightDepth++; }
if (leftDepth == rightDepth){ return (2 << leftDepth) - 1; } else { return countNodes(root.left) + countNodes(root.right) + 1; } } }
|
复习: 翻转二叉树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Solution { public TreeNode invertTree(TreeNode root) { if (root == null) return root; swapChildren(root); invertTree(root.left); invertTree(root.right); return root; }
public void swapChildren(TreeNode node){ TreeNode temp = node.left; node.left = node.right; node.right = temp; } }
|
复习: 对称二叉树
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public boolean isSymmetric1(TreeNode root) { return compare(root.left, root.right); }
private boolean compare(TreeNode left, TreeNode right) {
if (left == null && right != null) { return false; } if (left != null && right == null) { return false; }
if (left == null && right == null) { return true; } if (left.val != right.val) { return false; } boolean compareOutside = compare(left.left, right.right); boolean compareInside = compare(left.right, right.left); return compareOutside && compareInside; }
|