二叉搜索树定义
二叉搜索树(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 <= left
或root.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'))
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]
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
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)