Convert Sorted List to Balanced BST
Question:
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
Example:
2
1->2->3 => / \
1 3
Analysis:
有一道相似的题 “Convert Sorted Array to Balanced BST” ,解法是先找到数组的中间点,也就是树的根,然后递归地构建左子树和右子树,自上而下依次插入节点。用这种解法依赖于数组的index,因为每次递归需要找到数组的中间点来确定根的值。在数组中访问任意节点耗时O(1)。然而在linked list中,只能从头走到尾,因此找到中点耗时O(n),对比发现慢了许多。
我们想到,对于BST,中序遍历的结果是一个从小到大的有序序列。那么如果反过来,从左到右遍历linked list,利用类似中序遍历的方式构建BST应该可行。从下到上构建这棵树,用一个curt变量记录链表的当前节点。其中helper函数的定义是:将curt指针开头的,从start到end的list转变为BST,事后curt指针指向下一个node。
Code:
1 /** 2 * Definition for ListNode. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int val) { 7 * this.val = val; 8 * this.next = null; 9 * } 10 * } 11 * Definition of TreeNode: 12 * public class TreeNode { 13 * public int val; 14 * public TreeNode left, right; 15 * public TreeNode(int val) { 16 * this.val = val; 17 * this.left = this.right = null; 18 * } 19 * } 20 */ 21 public class Solution { 22 /** 23 * @param head: The first node of linked list. 24 * @return: a tree node 25 */ 26 private ListNode curt = null; 27 28 public TreeNode sortedListToBST(ListNode head) { 29 if(head == null) { 30 return null; 31 } 32 33 curt = head; 34 int length = getListLength(head); 35 return helper(0, length - 1); 36 } 37 38 private int getListLength(ListNode head) { 39 int length = 0; 40 while(head != null) { 41 head = head.next; 42 length++; 43 } 44 return length; 45 } 46 47 private TreeNode helper(int start, int end) { 48 if(start > end) { 49 return null; 50 } 51 52 int mid = start + (end - start) / 2; 53 TreeNode left = helper(start, mid - 1); 54 55 TreeNode root = new TreeNode(curt.val); 56 curt = curt.next; 57 58 TreeNode right = helper(mid + 1, end); 59 60 root.left = left; 61 root.right = right; 62 63 return root; 64 } 65 }
Complexity:
时间复杂度为O(n),n为树中节点的个数。
(如果用找中点的方法从上往下构建树,树高为logn,每一层找中点耗费O(n)时间,所以总共时间复杂度为O(n * logn))