给定一个单链表,其中的元素按升序排序,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
给定的有序链表: [-10, -3, 0, 5, 9],
一个可能的答案是:[0, -3, 9, -10, null, 5], 它可以表示下面这个高度平衡二叉搜索树:
0
/ \
-3 9
/ /
-10 5
第一次的代码:
最简单的就是将链表化成升序列表,当然这就没意思了。
思路也是找到中点,将链表分割然后递归。
geti函数计算链表长度,得到长度deep,deep//2得到链表中点,即root节点,那么即可将链表分为三段,即左树链表pre,中间root链表,右树链表pos。
s函数将分割后的链表递归成数。
def geti(l):
count=l
deep=0
while count :
deep+=1
count=count.next
pre=l
p=ListNode(pre.val)#计算左链表,从l第一个节点开始
p1=p#备份
for i in range((deep//2)-1):#当循环到中点前一个节点停止
pre=pre.next
p.next=ListNode(pre.val)#存储左树链表
p=p.next#记得更新链表
pre=pre.next#链表root中点节点
if pre:#表明中点节点非空,返回pre+root+pos
return p1,pre,pre.next#pre,root,pos,pre
else:#表明l只含有一个节点,则为root节点,返回空+该节点l+空
return None,l,None#pre,root,pos,pre
def s(l):
if not l:
return None
pre,ro,pos=geti(l)#得到pre+root+pos
root=TreeNode(ro.val)
root.left=s(pre)
root.right=s(pos)
return root
return s(head)
248ms,排名16%
别人所谓的快慢指针发其实和我上述代码思路差不多,都是找到中点然后分割,我也做一把吧:
快慢指针:
def geti(l):
pos=l
pre=l
p=root=ListNode(0)
while pos and pos.next:
root.next=ListNode(pre.val)#取中点节点前链表作为左树链表
root=root.next
pre=pre.next#最终指向中点
pos=pos.next.next
if pre:
root.next=None
return p.next,pre,pre.next
else:
return None,l,None
def s(l):
if not l:
return None
pre,ro,pos=geti(l)
root=TreeNode(ro.val)
root.left=s(pre)
root.right=s(pos)
return root
return s(head)
324ms,paim 5%