標籤:style blog color io ar for div sp log
Given preorder and inorder traversal of a tree, construct the binary tree.Note:You may assume that duplicates do not exist in the tree.
難度:95,參考了網上的思路。這道題是樹中比較有難度的題目,需要根據先序遍曆和中序遍曆來構造出樹來。這道題看似毫無頭緒,其實梳理一下還是有章可循的。下面我們就用一個例子來解釋如何構造出樹。
假設樹的先序遍曆是12453687,中序遍曆是42516837。這裡最重要的一點就是先序遍曆可以提供根的所在,而根據中序遍曆的性質知道根的所在就可以將序列分為左右子樹。比如上述例子,我們知道1是根,所以根據中序遍曆的結果425是左子樹,而6837就是右子樹。接下來根據切出來的左右子樹的長度又可以在先序便利中確定左右子樹對應的子序列(先序遍曆也是先左子樹後右子樹)。根據這個流程,左子樹的先序遍曆和中序遍曆分別是245和425,右子樹的先序遍曆和中序遍曆則是3687和6837,我們重複以上方法,可以繼續找到根和左右子樹,直到剩下一個元素。可以看出這是一個比較明顯的遞迴過程,對於尋找根所對應的下標,我們可以先建立一個HashMap,以免後面需要進行線行搜尋,這樣每次遞迴中就只需要常量操作就可以完成對根的確定和左右子樹的分割。
演算法最終相當於一次樹的遍曆,每個結點只會被訪問一次,所以時間複雜度是O(n)。而空間我們需要建立一個map來儲存元素到下標的映射,所以是O(n)。
1 /** 2 * Definition for binary tree 3 * public class TreeNode { 4 * int val; 5 * TreeNode left; 6 * TreeNode right; 7 * TreeNode(int x) { val = x; } 8 * } 9 */10 public class Solution {11 public TreeNode buildTree(int[] preorder, int[] inorder) {12 if (preorder.length == 0 || inorder.length == 0 || preorder.length != inorder.length) return null;13 int len = preorder.length;14 HashMap<Integer, Integer> map = new HashMap<Integer, Integer> ();15 for (int i=0; i<len; i++) {16 map.put(inorder[i], i);17 }18 return helper(preorder, 0, len-1, inorder, 0, len-1, map);19 }20 21 public TreeNode helper(int[] preorder, int preL, int preR, int[] inorder, int inL, int inR, HashMap<Integer, Integer> map) {22 if (preL > preR || inL > inR) {23 return null;24 }25 TreeNode root = new TreeNode(preorder[preL]);26 int index = map.get(preorder[preL]);27 root.left = helper(preorder, preL+1, preL+index-inL, inorder, inL, index-1, map);28 root.right = helper(preorder, preL+index-inL+1, preR, inorder, index+1, inR, map);29 return root;30 }31 }
Leetcode: Construct Binary Tree from Preorder and Inorder Transversal