给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
我的思路:采用快慢指针定位到链表的中间位置,然后就和108有序数组转换二叉搜索树一样了
代码如下:
public class Solution { public TreeNode sortedListToBST(ListNode head) { return buildTree(head, null); } public TreeNode buildTree(ListNode start,ListNode end){ if (start == end){ return null; } ListNode mid = getMedian(start, end); TreeNode root = new TreeNode(mid.val); root.left = buildTree(start, mid); root.right = buildTree(mid.next, end); return root; } public ListNode getMedian(ListNode start,ListNode end){ ListNode fast = start; ListNode slow = start; while (fast != end && fast.next != end){ fast = fast.next; fast = fast.next; slow = slow.next; } return slow; } }
结果:
官方给出了优化的方法:在分治的过程中,我们不用急着找出链表的中位数节点,而是使用一个占位节点,等到中序遍历到该节点时,再填充它的值。
代码如下:
class Solution {
ListNode globalHead;
public TreeNode sortedListToBST(ListNode head) {
globalHead = head;
int length = getLength(head);
return buildTree(0, length - 1);
}
public int getLength(ListNode head) {
int ret = 0;
while (head != null) {
++ret;
head = head.next;
}
return ret;
}
public TreeNode buildTree(int left, int right) {
if (left > right) {
return null;
}
int mid = (left + right + 1) / 2;
TreeNode root = new TreeNode();
root.left = buildTree(left, mid - 1);
root.val = globalHead.val;
globalHead = globalHead.next;
root.right = buildTree(mid + 1, right);
return root;
}
}