有序链表转二叉搜索树、二叉搜索平衡树
转二叉搜索树
二叉搜索树中序遍历得到有序数组的逆过程。
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
return dfs(nums, 0, nums.length - 1); // [0 , length - 1]
}
private TreeNode dfs(int[] nums, int low, int high) {
if (low > high) {
return null;
}
// 以升序数组的中间元素作为根节点 root。
int mid = low + (high - low) / 2;
TreeNode root = new TreeNode(nums[mid]);
// 递归的构建 root 的左子树与右子树。
// { [low , mid - 1] [mid] [mid + 1, high] }
root.left = dfs(nums, low, mid - 1);
root.right = dfs(nums, mid + 1, high);
return root;
}
}
转二叉搜索平衡树
二叉搜索平衡树就是每次按照链表的中间结点来做根结点。
快指针按照2
倍速增长,慢指针按照1
倍速增长,当快指针到达链表低的时候,慢指针的位置就是中间元素。
EXP:
Nodes's num = 9;
4s later: fast = 8, slow = 4.
abviously, (num + 1) / 2 is our ans, so need fast to move a incomplete move which means to move one more step;
After find the mid, we also need to break the old LinkedList, to create two new LinkedList;
[head, slow.pre] [slow] [slow.next, end];
[slow] will be used for the root node;
[head, slow.pre] will be used to be the root node's left child tree;
[slow.next, end] wiil be used to be the root node's right child tree;
CODING:
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, pre = null;
while (fast != null && fast.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
// 断开链表 使得后续分治得以进行
pre.next = null;
// 以升序链表的中间元素作为根节点 root,递归的构建 root 的左子树与右子树。
TreeNode root = new TreeNode(slow.val);
root.left = sortedListToBST(head); //旧链表左端起始
root.right = sortedListToBST(slow.next);// 拆分的新链表起始
return root;
}
}