669. 修剪二叉搜索树
给定一个二叉搜索树,同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树,使得所有节点的值在[L, R]中 (R>=L) 。你可能需要改变树的根节点,所以结果应当返回修剪好的二叉搜索树的新的根节点。
递归法(版本一)
class Solution:
def trimBST(self, root: TreeNode, low: int, high: int) -> TreeNode:
if root is None:
return None
if root.val < low:
# 寻找符合区间 [low, high] 的节点
return self.trimBST(root.right, low, high)
if root.val > high:
# 寻找符合区间 [low, high] 的节点
return self.trimBST(root.left, low, high)
root.left = self.trimBST(root.left, low, high) # root.left 接入符合条件的左孩子
root.right = self.trimBST(root.right, low, high) # root.right 接入符合条件的右孩子
return root
这段代码是一个修剪二叉搜索树的函数,使得树中所有节点的值都在给定的范围 [low, high]
内。以下是代码的详细步骤:
- 首先,我们检查根节点是否为空。如果为空,那么我们直接返回空。
- 然后,我们检查根节点的值是否小于
low
。如果是,那么我们知道左子树中的所有节点都会小于low
,所以我们可以放心地删除左子树,并在右子树中递归地寻找符合区间[low, high]
的节点。 - 如果根节点的值大于
high
,那么我们知道右子树中的所有节点都会大于high
,所以我们可以放心地删除右子树,并在左子树中递归地寻找符合区间[low, high]
的节点。 - 如果根节点的值在区间
[low, high]
内,那么我们需要在左右子树中分别递归地寻找符合区间[low, high]
的节点,并将找到的节点接入到当前根节点的左右孩子位置。 - 最后,返回处理后的根节点。
这个函数假设给定的二叉树是一个有效的二叉搜索树。
108.将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
示例:
递归法
class Solution:
def traversal(self, nums: List[int], left: int, right: int) -> TreeNode:
if left > right:
return None
mid = left + (right - left) // 2
root = TreeNode(nums[mid])
root.left = self.traversal(nums, left, mid - 1)
root.right = self.traversal(nums, mid + 1, right)
return root
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
root = self.traversal(nums, 0, len(nums) - 1)
return root
这段代码是一个将排序数组转换为二叉搜索树的函数。以下是代码的详细步骤:
- 首先,我们定义了一个名为
traversal
的递归函数,它接受一个排序数组nums
和两个索引left
和right
作为输入。这个函数的目标是创建一个二叉搜索树,其中所有节点的值都来自数组nums
中索引在left
和right
之间的元素。 - 在
traversal
函数中,我们首先检查left
是否大于right
。如果是,那么我们返回空,因为这意味着没有更多的元素可以添加到树中。 - 然后,我们计算中间索引
mid
,并创建一个新的树节点,其值为nums[mid]
。 - 接下来,我们递归地在左子树和右子树中添加节点。对于左子树,我们处理数组中索引在
left
到mid - 1
之间的元素;对于右子树,我们处理数组中索引在mid + 1
到right
之间的元素。 - 最后,我们返回创建的根节点。
- 在主函数
sortedArrayToBST
中,我们调用了traversal
函数,并传入了整个数组以及初始的左右索引(0 和len(nums) - 1
)。然后返回创建的根节点。
这个函数假设给定的数组已经排序。
538.把二叉搜索树转换为累加树
给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。
提醒一下,二叉搜索树满足下列约束条件:
节点的左子树仅包含键 小于 节点键的节点。 节点的右子树仅包含键 大于 节点键的节点。 左右子树也必须是二叉搜索树。
示例 1:
- 输入:[4,1,6,0,2,5,7,null,null,null,3,null,null,null,8]
- 输出:[30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]
示例 2:
- 输入:root = [0,null,1]
- 输出:[1,null,1]
示例 3:
- 输入:root = [1,0,2]
- 输出:[3,3,2]
示例 4:
- 输入:root = [3,2,4,1]
- 输出:[7,9,4,10]
提示:
- 树中的节点数介于 0 和 104 之间。
- 每个节点的值介于 -104 和 104 之间。
- 树中的所有值 互不相同 。
- 给定的树为二叉搜索树。
递归法(版本一)
# 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 convertBST(self, root: TreeNode) -> 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)
- 首先,我们定义了一个名为
pre
的变量,用于记录前一个节点的值。初始时,pre
的值为 0。 - 然后,我们定义了一个名为
traversal
的递归函数,用于遍历树中的每个节点。这个函数接受一个节点cur
作为输入。 - 在
traversal
函数中,我们首先检查当前节点cur
是否为空。如果为空,那么我们直接返回。 - 然后,我们递归地遍历当前节点的右子树。因为在二叉搜索树中,一个节点的右子节点的值总是大于该节点的值。
- 接着,我们更新当前节点的值。新的值等于当前节点的原始值加上
pre
的值。 - 然后,我们将
pre
的值更新为当前节点的新值。这是因为在接下来的遍历中,当前节点将成为前一个节点。 - 最后,我们递归地遍历当前节点的左子树。因为在二叉搜索树中,一个节点的左子节点的值总是小于该节点的值。
在主函数 convertBST
中,我们调用了 traversal
函数,并传入了根节点。然后返回处理后的根节点。
这个函数假设给定的二叉树是一个有效的二叉搜索树。
"原始树中大于或等于该节点值的所有值之和"这句话的意思是,对于二叉搜索树中的任意一个节点,我们计算所有大于或等于(即,大于该节点值,或者就是该节点值)该节点值的节点的值的总和。这个总和就是新的节点值。
例如,假设我们有一个二叉搜索树如下:
5
/ \
2 13
对于节点 5
,原始树中大于或等于 5
的节点有 5
和 13
,所以新的节点值为 5 + 13 = 18
。
对于节点 2
,原始树中大于或等于 2
的节点有 2
, 5
, 和 13
,所以新的节点值为 2 + 5 + 13 = 20
。
对于节点 13
,原始树中大于或等于 13
的节点只有 13
,所以新的节点值仍然为 13
。
所以,转换后的累加树如下所示:
18
/ \
20 13