Convert Sorted List to Binary Search Tree (M)
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST.
For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.
Example:
Given the sorted linked list: [-10,-3,0,5,9],
One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST:
0
/ \
-3 9
/ /
-10 5
题意
将一个有序链表转换成左右子树高度差不超过1的平衡二叉查找树。
思路
比较简单的方法是,将链表中的值存入数组中,接下来与 108. Convert Sorted Array to Binary Search Tree 一样进行二分递归。
直接用快慢指针可以一次遍历找到链表中的中位数:初始时快慢指针同时指向头结点,每次移动慢指针走1步、快指针走2步,当快指针无法继续走时慢指针正好指在中位数处。每次找到当前链表的中位数作为当前子树的根,以中位数为中心划分出左右链表,递归生成左右子树。
模拟中序遍历:很玄妙,利用了二叉查找树的中序遍历是递增序列的性质,具体还是看官方解答 - Approach 3: Inorder Simulation。
代码实现 - 快慢指针
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode sortedListToBST(ListNode head) {
if (head == null) {
return null;
}
ListNode mid = findMid(head);
TreeNode x = new TreeNode(mid.val);
x.left = mid == head ? null : sortedListToBST(head);
x.right = sortedListToBST(mid.next);
return x;
}
private ListNode findMid(ListNode head) {
ListNode pre = null;
ListNode slow = head, fast = head;
while (fast.next != null && fast.next.next != null) {
pre = slow;
slow = slow.next;
fast = fast.next.next;
}
if (pre != null) {
pre.next = null;
}
return slow;
}
}
代码实现 - 模拟中序遍历
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
private ListNode head;
public TreeNode sortedListToBST(ListNode head) {
this.head = head;
// 求出链表长度
int len = 0;
ListNode p = head;
while (p != null) {
len++;
p = p.next;
}
return sortedListToBST(0, len - 1);
}
private TreeNode sortedListToBST(int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right) / 2;
TreeNode leftChild = sortedListToBST(left, mid - 1);
TreeNode root = new TreeNode(head.val);
root.left = leftChild;
head = head.next;
root.right = sortedListToBST(mid + 1, right);
return root;
}
}
本文介绍如何将一个按升序排列的单链表转换为高度平衡的二叉搜索树,通过快慢指针和模拟中序遍历两种方法实现。快慢指针法直接找出链表中位数作为根节点,而模拟中序遍历则利用了二叉查找树的性质。
377

被折叠的 条评论
为什么被折叠?



