109. 有序链表转换二叉搜索树

202 阅读1分钟

image.png

说白了就是链表转树,只是在这个基础上做了诸多的限制,比如这个链表要有序,因为要转成二叉搜索树,而且转成的树必须是高度平衡的,要满足高度平衡的树就必须从链表的中间位置开始,以中间节点作为根节点可以满足高度平衡这个条件,那么也就是要找中间节点,找中间点就会用到快慢指针,这里有一个点要知道,快慢节点是找中间节点,但是我们要把链表分开,就意味着我们要找到中间节点的前一个节点,怎么做?记不记得我们反转链表的方法,有一个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;
};