目录
Leetcode - 699
这题虽然代码不复杂,但是挺难想的,最核心的一点就是要考虑到待删除节点的字数,若一个节点的值小于左边界,但是这个节点可能存在右子树,且由于右子树里的节点都大于该节点,所以是可能存在区间内部的点,此时要继续向右递归。同理,节点的值大于右边界,就要考虑左子树,再进行一次递归。此时递归后的结果应该返回给上上层 (因为这里是两次递归),也就是节点的父节点。
小于左边界的节点,肯定是存在于左子树中的,这里可能会有疑问,这种节点可能也存在于右子树中? 是的,因为这里我们把判断逻辑写在前面,左右递归写在后面,所以是先序遍历,先序遍历中肯定是一直往左找,直到找到符合删除条件的节点,此时我们再往右进行第二次遍历,返回的结果就是一颗干净的右子树了,直接作为父节点的左孩子
def trimBST(self, root: Optional[TreeNode], low: int, high: int) -> Optional[TreeNode]:
def delete(root,low,high):
if root == None:
return root
if root.val < low:
right = delete(root.right,low,high)
return right
if root.val > high:
left = delete(root.left,low,high)
return left
root.left = delete(root.left,low,high)
root.right = delete(root.right,low,high)
return root
return delete(root,low,high)
这里也可以这样解释,在找到符合小于左边界的节点前,我们是跳过了前面的判断逻辑,一直在执行delete(root.left,low,high),所以肯定是现在左子树中找到目标节点,然后将一颗干净的数返回给父节点的左边。 右子树同理
Leetcode - 108
这题就是一个不断二分的过程,每次对数组平均划分为两部分,高度差不会超过1,先取中间节点为跟节点,通过根节点在数组中的Index,划分左右子树,终止条件就是对子树区间的判断,若为空(如长度为1的数组,1//2 =0,那么左子树就为空),返回None, 若只有一个元素,那么就返回以这个元素为值的node。右子树在划分时的形式是[index+1:]但是有可能index+1会越界,这里需要加一个判断,若越界。则说明右子树为空,直接root.right = None,若不为空,则将右区间传入递归并返回给右节点,因为左子树不会出现越界异常,可直接通过终止条件来判断,不需要额外加判断。
def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
def create(nums):
if len(nums)==1:
return TreeNode(val = nums[0])
if nums == []:
return None
index = len(nums)//2
root = TreeNode(val = nums[index])
if index +1 < len(nums):
right = nums[index+1:]
root.right = create(right)
else:
root.right = None
left = nums[:index]
root.left = create(left)
return root
return create(nums)
Leetcode - 538
我们知道如果中序遍历,对于排序二叉树来说就是一个由小到大的有序序列。本题要求当前节点的值要加上所有比自己大的节点的值,那么对于序列来说,就是加上排在自己后面的数的值,那其实可以这样看,倒数第一个元素因为后面没数,所以不加,倒数第二个元素加上倒数第一个的值,倒数第三个加上倒数第二和倒数第一的值,其实这里就等于直接加上更新后的倒数第二个元素的值,其实就是一个逆向的累加的过程。所以 我们可以做一个中序的逆向遍历,然后用Pre指针指向上一个节点,然后每次root的值就加上Pre的值即可。
def convertBST(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
pre = TreeNode()
def accumulate(root):
nonlocal pre
if not root:
return None
accumulate(root.right)
root.val += pre.val
pre = root
accumulate(root.left)
accumulate(root)
return root