题目描述
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ 9 20
/ 15 7
分析
这题剑指offer中出现过,虽然通过了,但是提交到leetcode上就特别差:
56 ms 75.9 MB
又看了别人的思路:
(递归) O(n)
递归建立整棵二叉树:先递归创建左右子树,然后创建根节点,并让指针指向两棵子树。
具体步骤如下:
- 先利用前序遍历找根节点:前序遍历的第一个数,就是根节点的值;
- 在中序遍历中找到根节点的位置 k,则 k左边是左子树的中序遍历,右边是右子树的中序遍历;
- 假设左子树的中序遍历的长度是 l,则在前序遍历中,根节点后面的 l个数,是左子树的前序遍历,剩下的数是右子树的前序遍历;
- 有了左右子树的前序遍历和中序遍历,我们可以先递归创建出左右子树,然后再创建根节点;
时间复杂度分析:我们在初始化时,用哈希表(unordered_map<int,int>)记录每个值在中序遍历中的位置,这样我们在递归到每个节点时,在中序遍历中查找根节点位置的操作,只需要 O(1)
的时间。此时,创建每个节点需要的时间是 O(1),所以总时间复杂度是 O(n)。
8 ms 37.8 MB
贴出代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
int[] curr = {0};
TreeNode root;
Map<Integer, Integer> inMap = new HashMap<>();
for (int i = 0 ;i < inorder.length; i ++){
inMap.put(inorder[i],i);
}
root = dfs(preorder,curr,0,preorder.length - 1,inMap);
return root;
}
private TreeNode dfs(int[] pre, int[] curr, int low, int high, Map<Integer,Integer> inMap){
if (curr[0] >= pre.length)
return null;
TreeNode root = new TreeNode(pre[curr[0]]);
if (low > high){
return null;
}else {
curr[0] += 1;
int i = inMap.get(root.val);
root.left = dfs(pre,curr,low,i - 1,inMap);
root.right = dfs(pre,curr,i + 1,high,inMap);
}
return root;
}
}
原文地址:https://www.cnblogs.com/Tu9oh0st/p/10900210.html
时间: 2024-10-29 04:36:05