【树】力扣669:修剪二叉搜索树
给你二叉搜索树的根节点 root,同时给定最小边界 low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在 [low, high] 中。修剪树 不应该 改变保留在树中的元素的相对结构 (即,如果没有被移除,原有的父代子代关系都应当保留)。 可以证明,存在 唯一的答案 。
所以结果应当返回修剪好的二叉搜索树的新的根节点。注意,根节点可能会根据给定的边界发生改变。
示例:
输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3
输出:[3,2,null,1]
二叉搜索树的特点:node.left < node < node.right
递归
对于二叉数的递归,要想清楚当前的 root 结点需要干什么
# 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 trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root:
return
# 找到符合区间范围的结点
if root.val < low: # 如果当前结点的值小于 low:递归右子树,剪裁后重新赋值给当前结点 root
root = self.trimBST(root.right, low, high)
elif root.val > high: # 如果当前结点的值大于 high:递归左子树,剪裁后重新赋值给当前结点 root
root = self.trimBST(root.left, low, high)
else: # 结点值在区间范围内:将下一层处理完左子树的结果赋给 root.left,处理完右子树的结果赋给 root.right
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
return root
注意,调用本身这个函数加上 self.
。
如果不喜欢用 self
,可以定义一个辅函数,在主函数中直接运行辅函数。
class Solution(object):
def trimBST(self, root, L, R):
def trim(node):
if not node:
return None
elif node.val > R:
return trim(node.left)
elif node.val < L:
return trim(node.right)
else:
node.left = trim(node.left)
node.right = trim(node.right)
return node
return trim(root)
时间复杂度:O(N),其中 N 是给定的树的全部结点。最多每个结点访问一次。
空间复杂度:O(N),即使没有明确使用任何额外的内存,在最糟糕的情况下,递归调用的栈可能与结点数一样大。
迭代
在进行二叉树剪枝的时候,可以分为三步:
- 将 root 移动到 [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
总体代码:
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if not root:
return
# 根结点 root 的值不在区间内:向下找到适合的结点作为新的根结点 root,想象为新树
while root and (root.val < low or root.val > high):
if root.val < low:
root = root.right
else:
root = root.left
# 结点值在区间内:1. 左子树剪枝
cur = root
while cur:
while cur.left and cur.left.val < low:
cur.left = cur.left.right
cur = cur.left
# 结点值在区间内:2. 右子树剪枝
cur = root
while cur:
while cur.right and cur.right.val > high:
cur.right = cur.right.left
cur = cur.right
return root
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端