算法记录
LeetCode 题目:
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
说明
一、题目
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
二、分析
- 递归函数的参数三个,分别为前序遍历中的根节点、这个根节点开始的前序遍历的左边界,这个根节点开始的前序遍历的右边界
- 找到上面的根节点在中序遍历的位置,找到左子树的根节点以及其左右边界、右子树的根节点以及其左右边界,找到之后进行递归
- 左子树
- 左子树的根节点位置 = 根节点在前序遍历的位置 + 1
- 左边界 = 左边界
- 右边界 = 根节点在中序遍历的位置 -1
- 右子树
- 右子树的根节点位置 = 根节点在前序遍历的位置 + 左子树长度 + 1
- 左边界 = 根节点 + 1
- 右边界 = 右边界
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
Map<Integer, Integer> map = null;
int[] preorder = null;
public TreeNode buildTree(int[] preorder, int[] inorder) {
map = new HashMap<>();
this.preorder = preorder;
for (int i = 0; i < inorder.length; i++) {
map.put(inorder[i], i);
}
return builder(0, 0, inorder.length-1);
}
// node 为前序遍历节点为位置
TreeNode builder (Integer node, int left, int right) {
if (left > right ) {
// 表示该子树无节点,返回
return null;
}
// 划分左右子树
TreeNode result = new TreeNode(preorder[node]);
// 获取在前序遍历中根节点在中序遍历的位置
int i = map.get(preorder[node]);
// 递归左子树
result.left = builder(node+1, left, i-1);
// 递归柚子树
result.right = builder(i - left + node + 1, i + 1, right); // i - left + node + 1 中 (i - left 为左子树长度) ( node 为根节点索引 + 1)
// 返回节点
return result;
}
}