题目链接:https://leetcode.com/problems/convert-sorted-list-to-binary-search-tree/description/
题目大意:将升序单链表转换为平衡二叉排序树。
法一(借鉴):利用108的二分思想,只是这里单链表没法直接拿到下标,所以每次都要遍历得到最中间的数,可以计数链表长度,然后利用长度大小来遍历得到,这里时间复杂度变为o(nlgn),代码如下(耗时2ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public TreeNode sortedListToBST(ListNode head) { 2 int length = 0; 3 ListNode p = head; 4 while(head != null) { 5 head = head.next; 6 length++; 7 } 8 return dfs(p, length); 9 } 10 public static TreeNode dfs(ListNode head, int length) { 11 if(head == null || length == 0) { 12 return null; 13 } 14 ListNode p = head; 15 int leftLength = 1; 16 while(leftLength <= length / 2) { 17 head = head.next; 18 leftLength++; 19 } 20 TreeNode root = new TreeNode(head.val); 21 root.left = dfs(p, leftLength - 1); 22 root.right = dfs(head.next, length - leftLength); 23 return root; 24 }
法二(借鉴):依然是二分思想,但是这里不用Length计数链表长度来模拟二分,而是利用快慢指针来模拟二分,很巧妙,时间复杂度依然是o(nlgn),代码如下(耗时1ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public TreeNode sortedListToBST(ListNode head) { 2 return dfs(head, null); 3 } 4 public static TreeNode dfs(ListNode head, ListNode tail) { 5 if(head == tail) { 6 return null; 7 } 8 ListNode slow = head; 9 ListNode fast = head; 10 while(fast != tail && fast.next != tail) { 11 fast = fast.next.next; 12 slow = slow.next; 13 } 14 TreeNode root = new TreeNode(slow.val); 15 root.left = dfs(head, slow); 16 root.right = dfs(slow.next, tail); 17 return root; 18 }
法三:将结点放入集合中,模拟108数组的二分做即可,这里用LinkedList超时了,所以转而使用ArrayList,时间复杂度是o(n),代码如下(耗时2ms):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public TreeNode sortedListToBST(ListNode head) { 2 List<ListNode> list = new ArrayList<ListNode>(); 3 while(head != null) { 4 list.add(head); 5 head = head.next; 6 } 7 return dfs(list, 0, list.size() - 1); 8 } 9 public static TreeNode dfs(List<ListNode> list, int left, int right) { 10 if(left > right) { 11 return null; 12 } 13 int mid = (left + right) / 2; 14 TreeNode root = new TreeNode(list.get(mid).val); 15 root.left = dfs(list, left, mid - 1); 16 root.right = dfs(list, mid + 1, right); 17 return root; 18 }
法四(借鉴):还有一个利用中序创建二叉树的思想做的,时间复杂度是o(n),但空间复杂度是o(1),不是很懂,http://blog.csdn.net/feliciafay/article/details/18499545