LeetCode0105-从前序与中序遍历序列构造二叉树
题目:
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
分析:
二叉树前序遍历的顺序:
- 先遍历根节点
- 随后递归遍历左子树
- 随后递归遍历右子树
二叉树中序遍历的顺序:
- 先递归遍历左子树
- 随后遍历根节点
- 最后递归遍历右子树
方法:递归
思路
对于任意一棵树而言,前序遍历的形式总是:
[ 根节点,[左子树的前序遍历结果],[右子树的前序遍历结果]]
即根节点总是前序遍历的第一个节点。而中序遍历的形式总是:
[[左子树的中序遍历结果],根节点,[右子树的中序遍历结果]]
只要在中序遍历中定位到根节点,那么就可以分别知道左子树和右子树中的节点数目。由于同一颗子树的前序遍历和中序遍历的长度显然是相同的,因此就可以对应到前序遍历结果中,对上述形式中的所有左右括号进行定位。
这样就可以知道左子树的前序遍历和中序遍历结果,以及右子树的前序和中序遍历结果,就可以递归地对构造出左子树和右子树,再将俩棵树拼接到根节点的左右位置。
在中序遍历中,对根节点进行定位时,一种简单的方法是直接扫描整个中序遍历的结果并找出根节点。但这样做的时间复杂度较高。可以使用哈希映射(HashMap)来快速定位到根节点。对于哈希映射中的每个键值对,键表示一个元素(节点的值),值表示其在中序遍历中出现的位置。在构造二叉树的过程之前,可以对中序遍历进行一次扫描,就可以构造出哈希映射。在此后构造二叉树的过程中,只需要O(1)的时间对根进行定位。
代码:
package com.xujinshan.leetcode.code0105;
/**
* 0105-从前序与中序遍历序列构造二叉树
* 根据一棵树的前序遍历与中序遍历构造二叉树。
* <p>
* 注意:
* 你可以假设树中没有重复的元素。
* <p>
* 例如,给出
* <p>
* 前序遍历 preorder = [3,9,20,15,7]
* 中序遍历 inorder = [9,3,15,20,7]
* <p>
* 返回如下的二叉树:
* <p>
* 3
* / \
* 9 20
* / \
* 15 7
*/
import java.util.HashMap;
import java.util.Map;
/**
* Definition for a binary the tree node.
*/
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
/**
* 递归实现
*/
class Solution {
/**
* 通过HashMap 来快速定位根节点
* 对于HashMap 中的键值对,键表示一个元素(节点的值),值表示其在中序遍历中出现的位置
*/
private Map