LeetCode之有序链表转换二叉搜索树

141 阅读2分钟

题目链接

题目要求:这道题跟(由前序和中序遍历构造二叉树)相似

image.png

题目分析

  1. 二叉搜索树的中序遍历就是一个升序链表。
  2. 题目要求是一个高度平衡二叉树,所以二叉树的根节点应该设置成有序链表的中点。

解题步骤:

  1. 找根节点
  2. 找左右子树
  3. 构造节点
  4. 循环上面3个步骤

解题方法一:将有序链表转换成数组

//第一步遍历链表,转换成数组
let res=[]
while(head){
    res.push(head.val)
    head=head.next
}
function back(left,right){
    if(left>right){
        return null
    }
//找根节点索引
let index=Math.floor((left+right)/2)
//创建节点
let node=new TreeNode(res[index])
node.left=back(left,index-1)
node.right=back(index+1,right)
return node
}
return back(0,res.length-1)

解题方法二:找链表中点,分割链表

找链表中点小技巧

快慢指针:快指针走两步,慢指针走一步。当快指针走到终点,慢指针刚好走到了中点。

保存前驱节点技巧

let pre=node

node=node.next(这样就保存了node的前驱节点在pre上面)

var sortedListToBST = function(head) {
//方法二:找到链表的中间节点,然后分割链表
if(!head){
    return null
}
let fast=head
let slow=head
//为什么保存slow的前驱节点
//因为slow是中点,slow的左边是slow的左子树,slow的右边是他的右子树,需要通过这个前驱节点分割链表
let preSlow=null
//有一个不满足就不走
while(fast&&fast.next){
    //怎样保存前驱节点
    preSlow=slow
    slow=slow.next
    fast=fast.next.next
}
let node=new TreeNode(slow.val)
//为什么要进行这一步,如果只有一个节点时,fast.next==null,这时preSolw==null
//就直接return node
if(!preSlow){
    return node
}
preSlow.next=null
node.left=sortedListToBST(head)
node.right=sortedListToBST(slow.next)
return node
};

总结

根据【前序遍历】【中序遍历】【后序遍历】【链表】.....来构造二叉树的解题步骤

  1. 找根节点
  2. 找左右子树
  3. 创建根节点,连接左右子树
  4. 重复上面3个步骤