LeetCode50天刷题计划第二季(Day 11 — 将有序数组转换为二叉搜索树(12.00-12.40)有序链表转换二叉搜索树(12.20-12.40)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

昨天没写 今天还债

一、题目

将有序数组转换为二叉搜索树

给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。

高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。

示例

示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:

示例 2:
输入:nums = [1,3]
输出:[3,1]
解释:[1,null,3] 和 [3,1] 都是高度平衡二叉搜索树。

提示

1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums 按 严格递增 顺序排列
通过次数303,799提交次数393,735

二、思路

二叉搜索树的中序遍历是升序序列,也就是说,题目给定的数组是是二叉搜索树的中序遍历序列。但是由中序遍历序列并不能唯一地确定二叉搜索树。事实上,如果没有要求二叉搜索树的高度平衡,任何一个数字都可以作为二叉搜索树的根节点,导致可能的二叉搜索树有多个。

但如果要求高度平衡,其思路就是每次都选择序列的中间数字作为二叉搜索树的根节点,这样分给左右子树的数字个数相同或只相差 1,可以使得树保持平衡。如果数组长度是奇数,则根节点的选择是唯一的;如果数组长度是偶数,则可以选择中间位置左边的数字作为根节点或者选择中间位置右边的数字作为根节点。

因此我们可以看出,选择不同的数字作为根节点则创建的平衡二叉搜索树也是不同的。比如,题目中示例要求每次取中间位置或者中间位置右边的结点,作为根结点。此外,实现上采用递归建树。

三、代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        #根据例子,每次取中间位置或者中间位置右边的结点,作为根结点
        def sorted(start,end):
            #返回空节点
            if(start>end):
                return None
            #中间位置
            index=(start+end+1)//2
            #生成子树
            root=TreeNode(nums[index],None,None)
            root.left=sorted(start,index-1)
            root.right=sorted(index+1,end)
            #返回
            return root
        return sorted(0,len(nums)-1)


四、题目

有序链表转换二叉搜索树

给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为高度平衡的二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差不超过 1。

示例

示例 1:
输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。

示例 2:
输入: head = []
输出: []

提示:

head 中的节点数在[0, 2 * 104] 范围内
-105 <= Node.val <= 105

五、思路

跟前面的题思路一样,但链表的结点不能随机存取,找到中位值需要用快慢指针法,需要注意链表的一段序列可以用首指针和尾指针唯一标识(左闭右开),尾指针的初始值为None,此后每一次找到的中位结点都是前半段序列的尾指针(开),中位结点的下一个是后半段序列的首(闭)

六、代码

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sortedListToBST(self, head: Optional[ListNode]) -> Optional[TreeNode]:
        #给序列加一个头结点
        Head=TreeNode()
        #跟前面的题思路一样,但链表的结点不能随机存取,找到中位值需要用快慢指针法
        def findMid(head,rear): #找head后,rear前的中间结点(左闭右开)
            fast=slow=head
            while(fast != rear and fast.next!=rear): 
                slow=slow.next
                fast=fast.next.next
            return slow
        def sorted(head,rear): #对head后,rear前的节点序列构造子树
            if(head == rear):
                return None
            middle=findMid(head,rear) #找中间结点
            root=TreeNode(middle.val) #建立根结点
            root.left=sorted(head,middle)
            root.right=sorted(middle.next,rear)
            return root
        return sorted(head,None)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值