Convert Sorted List to Binary Search Tree
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; next = null; } 7 * } 8 */ 9 /** 10 * Definition for binary tree 11 * public class TreeNode { 12 * int val; 13 * TreeNode left; 14 * TreeNode right; 15 * TreeNode(int x) { val = x; } 16 * } 17 */ 18 public class Solution { 19 public class TreeNodes{ 20 TreeNode r; 21 TreeNode get(){return r;} 22 void set(int i){this.r.val = i;} 23 TreeNodes(){} 24 TreeNodes(TreeNode rr){this.r = rr;} 25 } 26 public TreeNodes root; 27 public TreeNode sortedListToBST(ListNode head) { 28 // Start typing your Java solution below 29 // DO NOT write main() function 30 ListNode temp = head; 31 root = new TreeNodes(new TreeNode(0)); 32 int length = 0; 33 while(temp!=null){ 34 temp=temp.next; 35 length++; 36 } 37 if(length == 0)return null; 38 toBST(head,0,length-1,root); 39 return root.get(); 40 } 41 42 43 public TreeNode toBST(ListNode head, int start, int end,TreeNodes r){ 44 if(start>end) return null; 45 46 int mid=(start+end)/2; 47 ListNode tmp = head; 48 for(int i = 0; i < mid; i ++){ 49 tmp = tmp.next; 50 } 51 r.set(tmp.val); 52 r.get().left = toBST(head, start,mid-1,new TreeNodes(new TreeNode(0))); 53 r.get().right = toBST(head, mid+1,end,new TreeNodes(new TreeNode(0))); 54 return r.get(); 55 } 56 }
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
If you have not checked out my previous post: Convert Sorted Array to Balanced Binary Search Tree (BST), you should check it out now as this solution is built upon the previous solution.
Things get a little more complicated when you have a singly linked list instead of an array. Please note that in linked list, you no longer have random access to an element in O(1) time.
Naive Solution:
A naive way is to apply the previous solution directly. In each recursive call, you would have to traverse half of the list’s length to find the middle element. The run time complexity is clearly O(N lg N), where N is the total number of elements in the list. This is because each level of recursive call requires a total of N/2 traversal steps in the list, and there are a total of lg N number of levels (ie, the height of the balanced tree).
Hint:
How about inserting nodes following the list’s order? If we can achieve this, we no longer need to find the middle element, as we are able to traverse the list while inserting nodes to the tree.
Best Solution:
As usual, the best solution requires you to think from another perspective. In other words, we no longer create nodes in the tree using the top-down approach. We create nodes bottom-up, and assign them to its parents. The bottom-up approach enables us to access the list in its order while creating nodes.
Isn’t the bottom-up approach neat? Each time you are stucked with the top-down approach, give bottom-up a try. Although bottom-up approach is not the most natural way we think, it is extremely helpful in some cases. However, you should prefer top-down instead of bottom-up in general, since the latter is more difficult to verify in correctness.
Below is the code for converting a singly linked list to a balanced BST. Please note that the algorithm requires the list’s length to be passed in as the function’s parameters. The list’s length could be found in O(N) time by traversing the entire list’s once. The recursive calls traverse the list and create tree’s nodes by the list’s order, which also takes O(N) time. Therefore, the overall run time complexity is still O(N).
1 BinaryTree*sortedListToBST(ListNode *&list,intstart,intend){ 2 if(start>end)returnNULL; 3 // same as (start+end)/2, avoids overflow 4 intmid=start+(end-start)/2; 5 BinaryTree *leftChild=sortedListToBST(list,start,mid-1); 6 BinaryTree *parent=newBinaryTree(list->data); 7 parent->left=leftChild; 8 list=list->next; 9 parent->right=sortedListToBST(list,mid+1,end); 10 returnparent; 11 } 12 13 BinaryTree*sortedListToBST(ListNode *head,intn){ 14 returnsortedListToBST(head,0,n-1); 15 }
还是和arraylist一样做,不过变成从底往上做。如果我们对一个BSF 做inorder search 会返回一个sorted list。故我们也是这么做它的。
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; next = null; } 7 * } 8 */ 9 /** 10 * Definition for binary tree 11 * public class TreeNode { 12 * int val; 13 * TreeNode left; 14 * TreeNode right; 15 * TreeNode(int x) { val = x; } 16 * } 17 */ 18 public class Solution { 19 public class Element{ 20 TreeNode tree; 21 ListNode list; 22 public Element(TreeNode t, ListNode l){ 23 tree = t; 24 list = l; 25 } 26 } 27 public TreeNode sortedListToBST(ListNode head) { 28 // IMPORTANT: Please reset any member data you declared, as 29 // the same Solution instance will be reused for each test case. 30 ListNode end = head; 31 int len = 0; 32 while(end != null){end = end.next; len ++;} 33 return buildTree(head, 0, len - 1).tree; 34 } 35 public Element buildTree(ListNode list, int s, int e){ 36 if(s > e) return new Element(null, list); 37 int mid = (s + e) / 2; 38 Element leftE = buildTree(list, s, mid - 1); 39 list = leftE.list; 40 TreeNode root = new TreeNode(list.val); 41 root.left = leftE.tree; 42 list = list.next; 43 Element rightE = buildTree(list, mid + 1, e); 44 list = rightE.list; 45 root.right = rightE.tree; 46 return new Element(root, list); 47 } 48 }
注意一个问题, list必须手动更新。因为java传的是引用,而不是指针!!! 很重要。
1 public class Solution { 2 public TreeNode sortedListToBST(ListNode head) { 3 // IMPORTANT: Please reset any member data you declared, as 4 // the same Solution instance will be reused for each test case. 5 ListNode end = head; 6 int len = 0; 7 while(end != null){ 8 end = end.next; 9 len ++; 10 } 11 return buildTree(head, 0, len - 1); 12 } 13 public TreeNode buildTree(ListNode list, int s, int e){ 14 if(s > e) return null; 15 int mid = (s + e) / 2; 16 TreeNode leftE = buildTree(list, s, mid - 1); 17 TreeNode root = new TreeNode(list.val); 18 root.left = leftE; 19 if(list.next != null){//Java pass in Object by reference, so we cannot change head but we can change its content!! 20 list.val = list.next.val; 21 list.next = list.next.next; 22 } 23 root.right = buildTree(list, mid + 1, e); 24 return root; 25 } 26 }
posted on 2013-09-12 14:46 Step-BY-Step 阅读(462) 评论(0) 编辑 收藏 举报