10.1 刷题心得
一、二叉树重建原理
通过二叉树的遍历序列(前序+中序或后序+中序)可反向重建原始二叉树结构,核心思路是:
- 利用遍历特性定位根节点
- 划分左右子树范围
- 递归重建整个树结构
二、遍历序列特性与根节点定位
-
前序遍历:
[根节点, 左子树前序, 右子树前序]
- 首元素即为当前树(或子树)的根节点
-
后序遍历:
[左子树后序, 右子树后序, 根节点]
- 尾元素即为当前树(或子树)的根节点
-
中序遍历:
[左子树中序, 根节点, 右子树中序]
- 根节点左侧为左子树所有节点
- 根节点右侧为右子树所有节点
三、重建步骤与数组范围处理
1. 确定根节点
- 从前序遍历首元素或后序遍历尾元素获取根节点
2. 划分左右子树(中序遍历中)
- 在中序遍历中找到根节点位置
rootIndex
- 左子树节点数:
leftSize = rootIndex
- 左子树中序序列:
[0, rootIndex)
(包含0,不包含rootIndex) - 右子树中序序列:
[rootIndex+1, inOrder.length)
3. 截取子树序列(关键应用 Arrays.copyOfRange())
Arrays.copyOfRange()
采用左闭右开原则:
- 包含起始索引(from)对应的元素
- 不包含结束索引(to)对应的元素
- 方法签名:
T[] copyOfRange(T[] original, int from, int to)
前序遍历截取示例:
// 左子树前序序列:从1开始(跳过根节点),长度为leftSize
int[] leftPre = Arrays.copyOfRange(preOrder, 1, 1 + leftSize);// 右子树前序序列:从左子树结束位置到数组末尾
int[] rightPre = Arrays.copyOfRange(preOrder, 1 + leftSize, preOrder.length);
后序遍历截取示例:
// 左子树后序序列:从0开始,长度为leftSize
int[] leftPost = Arrays.copyOfRange(postOrder, 0, leftSize);// 右子树后序序列:从左子树结束位置到倒数第二个元素(跳过根节点)
int[] rightPost = Arrays.copyOfRange(postOrder, leftSize, postOrder.length - 1);
4. 递归重建
- 用左子树序列递归构建左子树
- 用右子树序列递归构建右子树
- 将左右子树连接到根节点
四、注意事项
-
索引计算准确性:
- 确保
Arrays.copyOfRange()
的结束索引正确反映子树节点数量 - 避免数组越界(结束索引可等于数组长度,但不能小于起始索引)
- 确保
-
边界条件处理:
- 空序列(子树为空)时直接返回null
- 单节点序列直接返回该节点作为子树
-
序列组合限制:
- 必须使用中序遍历配合前序或后序遍历才能唯一确定二叉树
- 仅前序+后序遍历无法唯一确定树结构