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
与108题不同,是链表而不是数组
第一想法是把链表转换成list(因为数组需要确定长度)
剩下的基本按108的思路 用二分查找把node一个一个添加
唯一不同的地方是取值 list的取值要用 list.get(mid).val
list的 get方法应该是个和获得指定索引值的元素,
小小的思考 为什么要加.val 如果不加报错无法转成int值
TreeNode root = new TreeNode(list.get(mid).val);
class Solution {
public TreeNode sortedListToBST(ListNode head) {
//方法一把链表存入list
List<ListNode> list = new ArrayList<>();
ListNode node = head;
while(null != node) {
list.add(node);
node = node.next;
}
return convert(list,0, list.size()-1);
}
TreeNode convert(List<ListNode> list, int from, int to) {
if(from > to) return null;
int mid = from + (to-from)/2;
TreeNode root = new TreeNode(list.get(mid).val);
if(null != root) {
root.left = convert(list, from, mid-1);
root.right = convert(list, mid+1, to);
}
return root;
}
}
但是这并不是最优方法
最优方法
采用递归的方式,
(一)找中间结点,构建根结点,
(二)中间结点左半部分构建左子树,
(三)中间结点的右部分构建右子树
是一个非常巧妙的方法
但是其中有几点不明白
为什么链表断开需要再连接上?
我不连接上也可以ac
但是必须要断开
if (head == null) {
return null;
}
// 链表只有一个结点
if (head.next == null) {
return new TreeNode(head.val);
}
ListNode fast = head.next.next; // 快速节点每次移动两个,mid 每次移动一个fast到结尾 mid 正好到中间
ListNode mid = head;
//找mid
while(fast!= null&&fast.next!=null){
mid = mid.next;
fast = fast.next.next;
}
//mid.next 作为根节点
TreeNode root = new TreeNode(mid.next.val);
root.right = sortedListToBST(mid.next.next);//递归,以下一个节点为头节点,找出右子树
// ListNode midNext = mid.next;
mid.next = null;//断开原列表,破坏原链表结构构成新链表
root.left = sortedListToBST(head);//左子节点
// mid.next = midNext;
return root;
}
}