105. 从前序与中序遍历序列构造二叉树
Posted 可持续化发展
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了105. 从前序与中序遍历序列构造二叉树相关的知识,希望对你有一定的参考价值。
给定一棵树的前序遍历 preorder
与中序遍历 inorder
。请构造二叉树并返回其根节点。
示例 1:
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
示例 2:
Input: preorder = [-1], inorder = [-1] Output: [-1]
提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均无重复元素
inorder 均出现在 preorder
preorder 保证为二叉树的前序遍历序列
inorder 保证为二叉树的中序遍历序列
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
首先根据 preorder 找到根节点是 3
然后根据根节点将 inorder 分成左子树和右子树
左子树
inorder [9]右子树
inorder [15,20,7]把相应的前序遍历的数组也加进来
左子树
preorder[9]
inorder [9]右子树
preorder[20 15 7]
inorder [15,20,7]现在我们只需要构造左子树和右子树即可,成功把大问题化成了小问题
然后重复上边的步骤继续划分,直到 preorder 和 inorder 都为空,返回 null 即可
解题思路:
画一个完全二叉树,自己举个例子。再用上递归的思想,写出递归的通用表达式。
import java.util.HashMap;
import java.util.Map;
/**
* 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;
* }
* }
*/
/**
* 题目说了数组中无重复元素,所以可以用map来装中序遍历序列,
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
//构造map 装中序遍历数组,为了后面能直接获得preorder元素在inorder数组中的索引
Map<Integer , Integer> map = new HashMap<>();
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i], i);
}
return buildTree(preorder, 0, preorder.length-1, inorder, 0, inorder.length-1, map);
}
private TreeNode buildTree(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd, Map<Integer, Integer> inMap) {
//递归终止条件:
if (preStart > preEnd || inStart > inEnd){
return null;
}
//前序遍历的本质,构造root 节点
TreeNode root = new TreeNode(preorder[preStart]);
//获取root 节点在inorder中的索引。根据这个索引,划分inorder
int inRoot = inMap.get(root.val);
//获取偏移量
int numsLeft = inRoot - inStart;
//参数说明
//(preorder; root节点已经构造了,左子树的preorder数组的头索引;左子树的preorder数组的尾索引;inorder;左子树的inorder数组的头索引;左子树的inorder数组的尾索引;inMap)
//实际上是,以root元素在inorder数组中的位置为界限,重新划分出当前root节点的左右子树的 preorder 和 inorder
root.left = buildTree(preorder, preStart +1, preStart + numsLeft, inorder, inStart, inRoot - 1, inMap);
//...
root.right = buildTree(preorder, preStart + numsLeft+1, preEnd, inorder, inRoot + 1, inEnd, inMap);
return root;
}
}
以上是关于105. 从前序与中序遍历序列构造二叉树的主要内容,如果未能解决你的问题,请参考以下文章
leetcode-105,106 从前序与中序遍历序列构造二叉树,从中序与后序遍历序列构造二叉树