题目列表
144. 二叉树的前序遍历
94. 二叉树的中序遍历
145. 二叉树的后序遍历
102. 二叉树的层序遍历
107. 二叉树的层序遍历 II
103. 二叉树的锯齿形层序遍历
105. 从前序与中序遍历序列构造二叉树
106. 从中序与后序遍历序列构造二叉树
144. 二叉树的前序遍历
题目
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,2,3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
示例 5:
输入:root = [1,null,2]
输出:[1,2]
提示:
- 树中节点数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
思路
- 递归
- 非递归
答案
// 递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
helper(result, root);
return result;
}
public void helper(List<Integer> result, TreeNode root) {
if (root == null) {
return;
}
result.add(root.val);
helper(result, root.left);
helper(result, root.right);
}
}
// 非递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
List<TreeNode> stack = new LinkedList<>();
if (root != null) {
stack.addLast(root);
}
while (!stack.isEmpty()) {
TreeNode current = stack.removeLast();
result.add(current.val);
if (current.right != null) {
stack.addLast(current.right);
}
if (current.left != null) {
stack.addLast(current.left);
}
}
return result;
}
}
94. 二叉树的中序遍历
题目
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
思路
- 递归
- 非递归,模拟栈
答案
// 递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
helper(root, result);
return result;
}
public void helper(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
helper(root.left, result);
result.add(root.val);
helper(root.right, result);
}
}
// 非递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
List<TreeNode> stack = new LinkedList<>();
while (root != null || !stack.isEmpty()) {
while (root != null) {
stack.add(root);
root = root.left;
}
TreeNode current = stack.removeLast();
result.add(current.val);
if (current.right != null) {
root = current.right;
}
}
return result;
}
}
145. 二叉树的后序遍历
题目
给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[3,2,1]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点的数目在范围 [0, 100] 内
- -100 <= Node.val <= 100
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
思路
- 递归
- 非递归,和之前一样
答案
// 递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new ArrayList<>();
helper(root, result);
return result;
}
public void helper(TreeNode root, List<Integer> result) {
if (root == null) {
return;
}
helper(root.left, result);
helper(root.right, result);
result.add(root.val);
}
}
// 非递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> result = new LinkedList<>();
List<TreeNode> stack = new LinkedList<>();
if (root != null) {
stack.add(root);
}
while (!stack.isEmpty()) {
TreeNode current = stack.removeLast();
result.addFirst(current.val);
if (current.left != null) {
stack.addLast(current.left);
}
if (current.right != null) {
stack.addLast(current.right);
}
}
return result;
}
}
102. 二叉树的层序遍历
题目
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000] 内
- -1000 <= Node.val <= 1000
思路
找个队列,用来遍历
答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
List<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.add(root);
}
while (!queue.isEmpty()) {
List<Integer> temp = new ArrayList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode current = queue.removeFirst();
temp.add(current.val);
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}
result.add(temp);
}
return result;
}
}
107. 二叉树的层序遍历 II
题目
给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000] 内
- -1000 <= Node.val <= 1000
思路
和上一题一样
答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
List<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.add(root);
}
while (!queue.isEmpty()) {
List<Integer> temp = new ArrayList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode current = queue.removeFirst();
temp.add(current.val);
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}
result.addFirst(temp);
}
return result;
}
}
103. 二叉树的锯齿形层序遍历
题目
给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:[[3],[20,9],[15,7]]
示例 2:
输入:root = [1]
输出:[[1]]
示例 3:
输入:root = []
输出:[]
提示:
- 树中节点数目在范围 [0, 2000] 内
- -100 <= Node.val <= 100
思路
和层序遍历的区别是,要区分奇偶,控制头插还是尾插
答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
List<TreeNode> queue = new LinkedList<>();
if (root != null) {
queue.add(root);
}
boolean order = true;
while (!queue.isEmpty()) {
List<Integer> temp = new ArrayList<>();
int size = queue.size();
for (int i = 0; i < size; i++) {
TreeNode current = queue.removeFirst();
if (order) {
temp.addLast(current.val);
} else {
temp.addFirst(current.val);
}
if (current.left != null) {
queue.add(current.left);
}
if (current.right != null) {
queue.add(current.right);
}
}
order = !order;
result.add(temp);
}
return result;
}
}
105. 从前序与中序遍历序列构造二叉树
题目
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例 1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]
提示:
- 1 <= preorder.length <= 3000 inorder.length == preorder.length
- -3000 <= preorder[i], inorder[i] <= 3000
- preorder 和 inorder 均 无重复 元素
- inorder 均出现在 preorder
- preorder 保证 为二叉树的前序遍历序列
- inorder 保证 为二叉树的中序遍历序列
思路
递归构建,只要搞清楚,每个部分由先序和中序的哪个部分构成就行了
答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder, inorder, 0, preorder.length - 1, 0, inorder.length - 1);
}
public TreeNode buildTree(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd) {
// 结束条件
if (preStart > preEnd || inStart > inEnd) {
return null;
}
// 找到本次的根
int value = preorder[preStart];
// 找到根在中序的坐标,根据中序的特性,坐标的左边是左子树,右边是右子树
int inOrderIndex = findIndexInorder(inorder, value);
// 算一下左子树有几个元素,方便在先序中确认左子树的结束坐标
int leftNodeSize = inOrderIndex - inStart;
// 看着例一写就行了
int leftNextPreStart = preStart + 1;
int leftNextPreEnd = leftNextPreStart + leftNodeSize - 1;
int rightNextPreStart = leftNextPreEnd + 1;
int rightNextPreEnd = preEnd;
int leftNextInStart = inStart;
int leftNextInEnd = inOrderIndex - 1;
int rightNextInStart = inOrderIndex + 1;
int rightNextInEnd = inEnd;
TreeNode left = buildTree(preorder, inorder, leftNextPreStart, leftNextPreEnd, leftNextInStart, leftNextInEnd);
TreeNode right = buildTree(preorder, inorder, rightNextPreStart, rightNextPreEnd, rightNextInStart, rightNextInEnd);
return new TreeNode(value, left, right);
}
public int findIndexInorder(int[] inorder, int target) {
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == target) {
return i;
}
}
return -1;
}
}
106. 从中序与后序遍历序列构造二叉树
题目
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例 2:
输入:inorder = [-1], postorder = [-1]
输出:[-1]
提示:
- 1 <= inorder.length <= 3000
- postorder.length == inorder.length
- -3000 <= inorder[i], postorder[i] <= 3000
- inorder 和 postorder 都由 不同 的值组成
- postorder 中每一个值都在 inorder 中
- inorder 保证是树的中序遍历
- postorder 保证是树的后序遍历
思路
和之前一样
答案
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
return buildTree(inorder, postorder, 0, inorder.length - 1, 0, postorder.length - 1);
}
public TreeNode buildTree(int[] inorder, int[] postorder, int inOrderStart, int inOrderEnd, int postOrderStart, int postOrderEnd) {
if (inOrderStart > inOrderEnd || postOrderStart > postOrderEnd) {
return null;
}
int value = postorder[postOrderEnd];
int inOrderIndex = find(inorder, value);
int leftNodeSize = inOrderIndex - inOrderStart;
int leftInOrderStart = inOrderStart;
int leftInOrderEnd = inOrderStart + leftNodeSize - 1;
int rightInOrderStart = inOrderIndex + 1;
int rightInOrderEnd = inOrderEnd;
int leftPostOrderStart = postOrderStart;
int leftPostOrderEnd = leftPostOrderStart + leftNodeSize - 1;
int rightPostOrderStart = leftPostOrderEnd + 1;
int rightPostOrderEnd = postOrderEnd - 1;
TreeNode left = buildTree(inorder, postorder, leftInOrderStart, leftInOrderEnd, leftPostOrderStart, leftPostOrderEnd);
TreeNode right = buildTree(inorder, postorder, rightInOrderStart, rightInOrderEnd, rightPostOrderStart, rightPostOrderEnd);
return new TreeNode(value, left, right);
}
public int find(int[] inorder, int target) {
for (int i = 0; i < inorder.length; i++) {
if (inorder[i] == target) {
return i;
}
}
return -1;
}
}