welcome to my blog
LeetCode Top 100 Liked Questions 105. Construct Binary Tree from Preorder and Inorder Traversal (Java版; Medium)
题目描述
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
For example, given
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
Return the following binary tree:
3
/ \
9 20
/ \
15 7
第一次做; 递归函数逻辑:当前条件(数组范围), 新条件(新的数组范围); 注意index的初始化,循环条件!!; 看注释, 理解递归逻辑就理解了这道题的整体框架
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if(preorder == null || preorder.length==0)
return null;
TreeNode head = Core(preorder, inorder, 0, preorder.length-1, 0, inorder.length-1);
return head;
}
//递归函数逻辑:在当前条件(数组的范围)下找出根节点, 将根节点连向左子树的根节点(新条件新递归)和右子树(新条件新递归)(可以提前判断是否有左/右子树, 这样能减少一次递归), 最后返回当前条件下的根节点
public TreeNode Core(int[] preorder, int[] inorder, int preLeft, int preRight, int inLeft, int inRight){
//base case: 取决于当前条件
if(preLeft==preRight){
return new TreeNode(preorder[preLeft]);
}
//找出根节点: 前序遍历的第一个元素就是根节点的val
TreeNode root = new TreeNode(preorder[preLeft]);
//找出左右子树的范围
int index = inLeft;
//index指向的值等于root.val后便不会再进入循环执行index++操作了, 注意理解index的初始化,循环条件以及更新之间的联系
//index最终指向root.val在中序遍历数组中的位置; index的大小不是左子树的长度, index-inLeft才表示左子树的长度, 这里要小心
while(inorder[index] != preorder[preLeft]){
index++;
}
//新条件新递归
//如果有左子树的话
if(index > inLeft){
root.left = Core(preorder, inorder, preLeft+1, preLeft+index-inLeft, inLeft, index-1);
}
//如果有右子树的话
if(index < inRight){
root.right = Core(preorder, inorder, preLeft+index-inLeft+1, preRight, index+1, inRight);
}
return root;
}
}
上面递归做法的时间复杂度可以用Master公式分析; 注意d的含义
递归的时间复杂度分析
子问题规模相同时可以使用master公式
T(N):主函数
a:在递归函数中调用递归函数的次数,比如两个子问题,那么a就等于2
b:子问题的数据量, 比如两个子问题分别处理N/2的数据, 那么b就等于2
O(N^d):表示的是递归函数中,除去调用递归函数后的时间复杂度
- 官方题解也是使用的Master公式(主定理)分析