本文正在参与掘金团队号上线活动,点击 查看大厂春招职位
一、题目描述:
这个题目说的是,给你一棵二叉树的中序和后序遍历序列,你要根据这两个序列构建这棵二叉树。假设这棵二叉树节点上没有重复的数字。
比如说,给你的中序遍历序列和后序遍历序列分别是:
中序遍历序列:2, 1, 8, 4, 16
后序遍历序列:2, 8, 16, 4, 1
你要返回用它们构建出的二叉树,是:
1
/ \
2 4
/ \
8 16
二、思路分析:
解题步骤:
- 先找到根节点:在后序数组
- 再左右两边递归构造:在中序数组
可以使用一个
Map存储中序遍历的值和下标,用于快速访问。
三、AC 代码:
public class LeetCode_106 {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
// Time: o(n), Space: o(n), Faster: 66.41%
public TreeNode buildTree(int[] inorder, int[] postorder) {
Map<Integer, Integer> inPos = new HashMap<>();
for (int i = 0; i < inorder.length; ++i)
inPos.put(inorder[i], i);
return buildTree(postorder, 0, postorder.length - 1, 0, inPos);
}
private TreeNode buildTree(int[] post, int postStart, int postEnd, int inStart, Map<Integer, Integer> inPos) {
if (postStart > postEnd) return null;
TreeNode root = new TreeNode(post[postEnd]);
int rootIdx = inPos.get(post[postEnd]);
int leftLen = rootIdx - inStart;
root.left = buildTree(post, postStart, postStart + leftLen - 1, inStart, inPos);
root.right = buildTree(post, postStart + leftLen, postEnd - 1, rootIdx + 1, inPos);
return root;
}
}
四、总结:
树的遍历模板
树的遍历有四种:
- 前序遍历
- 中序遍历
- 后序遍历
- 层级遍历
这里也可以分为:深度优先遍历(DFS) 和 广度优先遍历 (BFS)
层级遍历:是为广度优先遍历。
其他遍历:是为深度优先遍历。
1. 前序遍历
void traverse(TreeNode root) {
if (null == root) return;
// 前序遍历的代码
traverse(root.left);
traverse(root.right);
}
2. 中序遍历
void traverse(TreeNode root) {
if (null == root) return;
traverse(root.left);
// 前序遍历的代码
traverse(root.right);
}
3. 后序遍历
void traverse(TreeNode root) {
if (null == root) return;
traverse(root.left);
traverse(root.right);
// 前序遍历的代码
}
4. 层级遍历
用队列模拟
void traverse(TreeNode root) {
if (null == root) return;
// 初始化队列,将 root 加入队列
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while (!q.isEmpty()) {
TreeNode cur = q.poll();
// 层级遍历代码
System.out.println(root.val);
if (cur.left != null) q.offer(cur.left);
if (cur.right != null) q.offer(cur.right);
}
}