669. 修剪二叉搜索树
解题思路:需要删除不在[low, high]范围内的值,满足low删除node的左子树和满足high删除node的右子树一定都不符合[low, high]。
所以如果要删除当前node满足low,只需考虑node的右子树;要删除当前node满足high,只需考虑node的左子树。
递归法:
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if root is None:
return None # 如果当前节点为空,直接返回 None
# 当前节点值小于范围下限,修剪左子树,返回修剪后的右子树
if root.val < low:
return self.trimBST(root.right, low, high)
# 当前节点值大于范围上限,修剪右子树,返回修剪后的左子树
if root.val > high:
return self.trimBST(root.left, low, high)
# 如果当前节点值在范围内,递归修剪左子树和右子树
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
return root # 返回修剪后的当前节点
迭代法:
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if root is None:
return None
# 修剪根节点,确保根节点在范围 [low, high] 内
while root and (root.val < low or root.val > high):
if root.val < low:
# 当前节点值小于范围下限,修剪左子树,移动到右子树
root = root.right
else:
# 当前节点值大于范围上限,修剪右子树,移动到左子树
root = root.left
# 修剪左子树
cur = root
while cur:
# 如果左子节点存在且小于范围下限,将其替换为右子节点
while cur.left and cur.left.val < low:
cur.left = cur.left.right # 跳过不符合条件的左子节点
cur = cur.left # 移动到下一个左子节点进行检查
# 修剪右子树
cur = root
while cur:
# 如果右子节点存在且大于范围上限,将其替换为左子节点
while cur.right and cur.right.val > high:
cur.right = cur.right.left # 跳过不符合条件的右子节点
cur = cur.right # 移动到下一个右子节点进行检查
return root
108. 将有序数组转换为二叉搜索树
递归法简单明了
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
538. 把二叉搜索树转换为累加树
解题思路:
1. 遍历顺序:使用反序中序遍历(右 -> 中 -> 左)来访问树,这样可以保证从大的节点开始依次累加。
2. 累加值记录:
• 使用 self.pre 来存储当前节点之前累加的所有值。
• 每次遍历到一个节点,将该节点的值加上 self.pre,并更新 self.pre 为该节点的新值。
class Solution:
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
# 初始化一个变量,用于存储累加的节点值
self.pre = 0
# 开始递归遍历树
self.traversal(root)
return root
def traversal(self, cur):
if cur is None:
return # 如果当前节点为空,则返回
# 递归遍历右子树,确保从最大的节点开始累加
self.traversal(cur.right) # 右
# 更新当前节点的值,将其加上之前累加的值
cur.val += self.pre # 中
# 更新累加值,用于下一个节点的累加
self.pre = cur.val # 记录当前节点的新值
# 递归遍历左子树,处理比当前节点小的节点
self.traversal(cur.left) # 左