O(NlogN)
先找中点,然后分别left right
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
}
if (head.next == null) {
return new TreeNode(head.val);
}
// 找链表中点
ListNode slow = head, fast = head;
ListNode preSlow = null; // to cut the list before mid
while (fast != null && fast.next != null) {
preSlow = slow;
slow = slow.next;
fast = fast.next.next;
}
// slow是中点
ListNode mid = slow;
// cut the list before mid!!
preSlow.next = null;
TreeNode root = new TreeNode(mid.val);
root.left = sortedListToBST(head);
root.right = sortedListToBST(mid.next);
return root;
}
}
O(logN)
- leftmost element in the inorder traversal has to be the head of our given linked list.
- Similarly, the next element in the inorder traversal will be the second element in the linked list and so on.
- so we can do sth like
➔ function formBst(start, end)
➔ mid = (start + end) / 2
➔ formBst(start, mid - 1)
➔
➔ TreeNode(head.val)
➔ head = head.next
➔
➔ formBst(mid + 1, end)
➔
模拟中序遍历
class Solution {
public TreeNode sortedListToBST(ListNode head) {
ListNode cur = head;
int len = 0;
while (cur != null) {
cur = cur.next;
len++;
}
curHead = head;
return buildBST(0, len - 1);
}
ListNode curHead;
public TreeNode buildBST(int start, int end) {
if (start > end) {
return null;
}
int mid = (start + end) / 2;
// inorder,先遍历left
TreeNode left = buildBST(start, mid - 1);
// inorder,遍历root
TreeNode root = new TreeNode(curHead.val);
root.left = left;
curHead = curHead.next;
// inorder,后遍历right
root.right = buildBST(mid + 1, end);
return root;
}
}