669. 修剪二叉搜索树
和删除 BST 节点的操作看上去很相似,同样是通过返回节点来重构 BST。但实际上比删除节点要简单:当因为上下限而删除节点的时候,直接返回相对应的递归后的左子树或者右子树即可。相比之下,删除特定节点需要在找到节点后手动进行删除,不能借助递归。
本题的重点在于,可以依靠返回值进行快速重构,同时意识到需要删除时应当递归其子树而不是直接返回 None。
class Solution:
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
if root == None:
return None
# leaf node, whether to trim or not
if root.left == None and root.right == None:
if root.val > high or root.val < low:
return None
else:
return root
# whether to trim current node
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
108. 将有序数组转换为二叉搜索树
构造 BST,一不小心就平衡了。 \hspace{40ex} - 代码随想录
根据数组构建 BST,重要的是找到左右区间。一般默认是取数组的中间元素作为节点,即可构成平衡 BST。
如果数组长度为偶数,中间节点有两个,此时取任意一节点都可以,答案不唯一。
可以通过传递当前区间的 index 来进一步优化空间使用,又要保证循环不变量:一直是左闭右开或者左闭右闭。
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if len(nums) == 0:
return None
if len(nums) == 1:
return TreeNode(val=nums[0])
mid_idx = len(nums) // 2
root = TreeNode(val=nums[mid_idx])
root.left = self.sortedArrayToBST(nums[:mid_idx])
root.right = self.sortedArrayToBST(nums[mid_idx+1:])
return root
538. 把二叉搜索树转换为累加树
将其看作是递增数组从右向左累加的话就很熟悉了,在 BST 中的遍历顺序应该是右中左。
同样可以通过双指针的方法,记录前一个节点的数值(已修改过),方便之后节点的累加。但直接依靠全局变量计算累加和更方便些。
class Solution:
def __init__(self):
self.increment = 0
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if root == None:
return None
# right
root.right = self.convertBST(root.right)
# middle
self.increment += root.val
root.val = self.increment
# left
root.left = self.convertBST(root.left)
return root
二叉树完结
二叉树的遍历方式:
- 深度优先
- 前序遍历:前左右
- 中序遍历:前中右
- 后序遍历:左右中
- 广度优先
- 层序遍历(队列)
遍历顺序的选择:
- 涉及到二叉树的构造,无论普通二叉树还是 BST 一定前序,都是先构造中节点。
- 求普通二叉树的属性,一般是后序,一般要通过递归函数的返回值做计算。
- 求二叉搜索树的属性,一定是中序了,要不白瞎了有序性。
注意在普通二叉树的属性中,我用的是一般为后序,例如单纯求深度就用前序。257 中也用了前序,这是为了方便让父节点指向子节点。
删除二叉搜索树中的节点 是一道值得再看的题。以重构的方式进行节点删除,免除了记录父节点的麻烦,是一个非常精妙的方法。同时,本题也有很多种终止条件的分类,值得理清思路。