基础数据结构篇(下)LeetCode 二叉搜索树算法题目

42 阅读3分钟

二叉搜索树定义

二叉搜索树(BST,Binary Search Tree)。一棵二叉树,可以为空;如果不为空,满足以下性质:

  • 非空左子树的所有键值小于其根结点的键值。
  • 非空右子树的所有键值大于其根结点的键值。
  • 左、右子树都是二叉搜索树。

二叉树定义

# 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

本次算法刷题 4 道二叉搜索树相关题目。

98. 验证二叉搜索树

解题思路

深度优先搜索。根据二叉搜索树定义,设定树的节点值下界 left 和上界 right
下界 left 初始是 float('-inf'),上界 right 初始是 float('-inf')

  • 若树为空,判定为真。
  • 检查根节点的值,若 root.val <= leftroot.val >= right,判断为假。
  • 递归检查左子树和右子树,左子树上界改为 root.val,右子树下界改为 root.val

代码

class Solution:
    def isValidBST(self, root: Optional[TreeNode]) -> bool:

        def check(root, left, right):
            if not root:
                return True
            if root.val <= left or root.val >= right:
                return False
            return check(root.left, left, root.val) and check(root.right, root.val, right)
        
        return check(root, float('-inf'), float('inf'))

image.png

703. 数据流中的第 K 大元素

解题思路

堆(heap),又称为优先队列(priority queue)。本题采用python自带的heapq模块。

from heapq import heapify, heappush, heappop, heapreplace

本题要求计算数据流中第 k 大元素。采用 python 默认的小根堆,堆顶元素是堆的最小值。 将数据 nums 元素存入堆中,保持堆的长度是 k,则堆顶元素即是第 k 大元素。

代码

class KthLargest:

    def __init__(self, k: int, nums: List[int]):
        self.h = nums
        heapify(self.h)
        self.k = k
        while len(self.h) > k:
            heappop(self.h)

    def add(self, val: int) -> int:
        if len(self.h) < self.k:
            heappush(self.h, val)
        elif val > self.h[0]:
            heapreplace(self.h, val)
        return self.h[0]

image.png

110. 平衡二叉树

解题思路

递归,深度优先搜索。
平衡二叉树定义是每个节点的左右子树的高度差绝对值不超过 1。
实现函数 f(root) 对每个节点进行检查,返回值有 2 个。第 1 个表示数是否平衡,第 2 个表示树的高度。
树的高度是左右子树的高度最大值 + 1。
平衡的判断根据定义是左右子树都平衡且左右子树高度差绝对值 <= 1

代码

class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def f(root):
            if not root:
                return True, 0
            fl, hl = f(root.left)
            fr, hr = f(root.right)
            balance = fl and fr and abs(hl - hr) <= 1
            h = max(hl, hr) + 1
            return balance, h
        balance, h = f(root)
        return balance

image.png

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

解题思路

类似于建立数的方法,采用递归的方式建立二叉搜索树。
根据二叉搜索树的性质

二叉搜索树的中序遍历可以得到递增排序的数组

根据题目要求,要根据有序数组创建高度平衡的二叉搜索树,那么可以把数组从中间分开,即 len(nums) // 2 作为根节点,左半部分为左子树,右半部分为右子树。
采用递归的方式分别创建左右子树,递归终止条件是数组为空,返回空树。

代码

class Solution:
    def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
        def dfs(nums):
            if not nums:
                return None
            k = len(nums) // 2
            root = TreeNode(nums[k])
            root.left = dfs(nums[:k])
            root.right = dfs(nums[k + 1:])
            return root
        return dfs(nums)

image.png

参考资料

github.com/datawhalech…