说白了就是链表转树,只是在这个基础上做了诸多的限制,比如这个链表要有序,因为要转成二叉搜索树,而且转成的树必须是高度平衡的,要满足高度平衡的树就必须从链表的中间位置开始,以中间节点作为根节点可以满足高度平衡这个条件,那么也就是要找中间节点,找中间点就会用到快慢指针,这里有一个点要知道,快慢节点是找中间节点,但是我们要把链表分开,就意味着我们要找到中间节点的前一个节点,怎么做?记不记得我们反转链表的方法,有一个pre节点,作为我们当前遍历节点的前一个节点,这里也可以这么使用。
var pre = null;
while (f !== null && f.next.next !==null) {
pre = s;
s = s.next;
f = f.next.next;
}
当这个循环结束的时候pre就在中间节点的前一个了。
所以回到这个题,找到中间节点,下一个就是找左右两个新的链表的中间节点,将其作为第一个根节点的左右子树的节点,依次递归。
var sortedListToBST = function(head) {
if (!head) return null;
if (!head.next) return new TreeNode(head.val);
var pre = null, s = head,f=head;
while(f!==null && f.next!==null) {
pre = s;
s = s.next;
f= f.next.next;
}
pre.next = null;
let v = new TreeNode(s.val);
v.left = sortedListToBST(head);
v.right = sortedListToBST(s.next);
return v;
};