目录
题目描述:
给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
代码部分:
(1)第一种方法
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
mid = len(nums) // 2
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid+1:])
return root
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
# 如果数组为空,返回 None
if not nums:
return None
# 找到数组的中间位置
mid = len(nums) // 2
# 以中间位置的值为根节点创建一个二叉搜索树
root = TreeNode(nums[mid])
# 递归地将左半部分的数组转换为左子树
root.left = self.sortedArrayToBST(nums[:mid])
# 递归地将右半部分的数组转换为右子树
root.right = self.sortedArrayToBST(nums[mid+1:])
# 返回根节点
return root
(2)第二种方法
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums:
return None
mid = len(nums) >> 1
root = TreeNode(nums[mid])
root.left = self.sortedArrayToBST(nums[:mid])
root.right = self.sortedArrayToBST(nums[mid+1:])
return root
题目解析:
(1)复杂度与思想
该代码的时间复杂度为 O(n),其中 n 为数组的长度。因为每个节点都会被遍历一次,且每次遍历的时间复杂度为 O(1)。
该题目涉及的知识点为二叉搜索树和递归。二叉搜索树是一种特殊的二叉树,它的左子树中的所有节点的值都小于根节点的值,右子树中的所有节点的值都大于根节点的值。递归是一种解决问题的方法,它将一个大问题分解成多个小问题,然后通过解决小问题来解决大问题。在该代码中,递归的思想被用来构建二叉搜索树。
(2)进阶分析:
本题要求将一个已经按升序排列的整数数组转换为一棵高度平衡的二叉搜索树。由于二叉搜索树的特性,我们可以通过二分法来构建一棵平衡的二叉搜索树。具体来说,我们可以选择数组的中间位置作为根节点,然后递归地构建左右子树。
具体实现上,我们定义一个递归函数 `sortedArrayToBST`,它接受一个整数数组 `nums` 作为参数,返回一棵高度平衡的二叉搜索树。如果 `nums` 为空,则返回空节点。否则,我们找到数组的中间位置 `mid`,将其作为根节点,然后递归地构建左右子树。左子树的数组范围是 `nums[:mid]`,右子树的数组范围是 `nums[mid+1:]`。递归的终止条件是数组为空。
代码实现上,我们可以使用 Python 的列表切片操作来获取子数组,然后递归调用 `sortedArrayToBST` 函数构建子树。最后返回根节点即可。
时间复杂度分析:每次递归都要对数组进行切片操作,时间复杂度为 $O(n)$,其中 $n$ 是数组的长度。由于每个节点都会被访问一次,因此总时间复杂度为 $O(n)$。
空间复杂度分析:每次递归都会创建一个新的节点,因此空间复杂度为 $O(n)$,其中 $n$ 是数组的长度。由于递归深度不超过 $\log n$,因此空间复杂度为 $O(\log n)$。
本题涉及的知识点包括二叉搜索树、递归、二分法等。二叉搜索树是一种常见的数据结构,它的特点是左子树的所有节点都小于根节点,右子树的所有节点都大于根节点。二分法是一种常见的算法思想,它可以用来在有序数组中查找元素、求解函数的零点等问题。递归是一种常见的算法实现方式,它可以用来解决树、图等数据结构的问题。
(3)二叉平衡树
二叉搜索树(Binary Search Tree,BST)是一种基于二叉树的数据结构,它具有以下特点:
1. 每个节点最多有两个子节点,左子节点的值小于父节点的值,右子节点的值大于父节点的值。
2. 对于任意节点,其左子树和右子树都是二叉搜索树。
3. 二叉搜索树的中序遍历是有序的。
二叉搜索树的主要应用是在查找、插入和删除操作中,它们的时间复杂度都是O(log n)。下面分别介绍这三个操作。
1. 查找操作
查找操作是指在二叉搜索树中查找某个节点。查找操作的过程是从根节点开始,如果目标节点的值小于当前节点的值,则在左子树中查找;如果目标节点的值大于当前节点的值,则在右子树中查找;如果目标节点的值等于当前节点的值,则找到了目标节点。如果查找到叶子节点仍然没有找到目标节点,则说明目标节点不存在于二叉搜索树中。
2. 插入操作
插入操作是指向二叉搜索树中插入一个新节点。插入操作的过程是从根节点开始,如果新节点的值小于当前节点的值,则在左子树中插入;如果新节点的值大于当前节点的值,则在右子树中插入。如果插入的位置已经存在节点,则更新该节点的值。
3. 删除操作
删除操作是指从二叉搜索树中删除一个节点。删除操作的过程比较复杂,需要考虑以下几种情况:
(1)如果要删除的节点是叶子节点,则直接删除该节点。
(2)如果要删除的节点只有一个子节点,则将该节点的子节点替换该节点。
(3)如果要删除的节点有两个子节点,则需要找到该节点的后继节点(即右子树中最小的节点),将后继节点的值复制到要删除的节点中,然后删除后继节点。
总结一下,二叉搜索树是一种非常重要的数据结构,它具有快速查找、插入和删除的优点。但是,二叉搜索树的性能取决于树的平衡性,如果树的高度过高,则操作的时间复杂度会退化为O(n),因此需要使用平衡二叉搜索树来解决这个问题。