问题
给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
例子
思路
-
方法1
把有序链表变成有序数组,问题就变成了108题
-
方法2
找到中间结点,该结点的值创造根结点,然后从该结点分成前后两截【使用一个指针表示前一段最后一个结点的前一个结点】,分别得到左子树和右子树,返回root
代码
//方法1
class Solution {
public TreeNode sortedListToBST(ListNode head) {
List<Integer> list = new ArrayList<>();
while(head!=null) {
list.add(head.val);
head = head.next;
}
return make(list,0,list.size()-1);
}
public TreeNode make(List<Integer> list, int l, int r) {
if(l>r) return null;
int m = l+(r-l)/2;
TreeNode root = new TreeNode(list.get(m));
root.left = make(list,l,m-1);
root.right = make(list,m+1,r);
return root;
}
}
//方法2
class Solution {
public TreeNode sortedListToBST(ListNode head) {
//方法1:先遍历获取递增数组,再造二叉树
//方法2:
if(head==null) return null;
else if(head.next==null) return new TreeNode(head.val);
//找到中间节点,可能为第一个,所以设置头节点
//4,5:slow=1,fast=2->2,3为中间节点
//4,5:slow=2,fast=3->3,3为中间节点
ListNode h = new ListNode(-1);
h.next = head;
//pre为中间节点的前一个节点,slow为中间节点
ListNode pre = h,slow=h.next,fast=h.next.next;
while(fast!=null && fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
pre = pre.next;
}
//使用两个指针,从中点把链表分开,pre为中点前面的那个
pre.next = null;
//slow:6个的第4个,5个的第三个
TreeNode root = new TreeNode(slow.val);
root.left = sortedListToBST(h.next);
root.right = sortedListToBST(slow.next);
return root;
}
}