二叉树篇-二叉搜索树
669. 修剪二叉搜索树
如果不对递归有深刻的理解,这道题目还是有难度的
我们写递归的逻辑,对于结点的处理,是要有返回值的,把根节点返回过去,最后才能用root.left, root.right接住返回值,返回root 传回构建出的树
我们遇到超出范围的node,直接返回None 是不对的,这样的话会把node的子树全部扔掉
其实可以根据二叉搜索树的条件去做
1.此时node.val 如果说 小于 low,那说明,它的左子树肯定小于low边界,处理它的右子树就行了,递归调用函数去对它的右子树修建一下,并返回
2.此时node.val如果说 大于high,那说明,它的右子树肯定大于high边界,处理它的左子树就行了,递归调用函数对它的左子树修建一下,并返回这个左子树
# 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 None
if root.val < low:
right = self.trimBST(root.right, low, high)
return right
if root.val > high:
left = self.trimBST(root.left, low, high)
return left
root.left = self.trimBST(root.left, low, high)
root.right = self.trimBST(root.right, low, high)
return root
108.将有序数组转换为二叉搜索树
这道题应该和 654.最大二叉树 106.从中序后序构建二叉树 这两道题放在一起,本质就是寻找分割点,分割点作为当前节点,然后递归左区间和右区间
题目中说要转换为一棵高度平衡二叉搜索树。这和转换为一棵普通二叉搜索树有什么差别呢?
其实这里不用强调平衡二叉搜索树,数组构造二叉树,构成平衡树是自然而然的事情,因为大家默认都是从数组中间位置取值作为节点元素,一般不会随机取,所以想构成不平衡的二叉树是自找麻烦。
分割点就是数组中间位置的节点。
那么为问题来了,如果数组长度为偶数,中间节点有两个,取哪一个?
取哪一个都可以,只不过构成了不同的平衡二叉搜索树。
那么这道题的代码和654.最大二叉树一模一样了感觉
# 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 sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:
if not nums: return None
root_val = nums[len(nums) // 2]
root = TreeNode(root_val)
leftnums = nums[:len(nums) // 2]
rightnums = nums[len(nums) // 2 + 1 :]
root.left = self.sortedArrayToBST(leftnums)
root.right = self.sortedArrayToBST(rightnums)
return root
题目链接
思路:
一看到累加树,相信很多小伙伴都会疑惑:如何累加?遇到一个节点,然后在遍历其他节点累加?怎么一想这么麻烦呢。
然后再发现这是一棵二叉搜索树,二叉搜索树啊,这是有序的啊。
那么有序的元素如果求累加呢?
其实这就是一棵树,大家可能看起来有点别扭,换一个角度来看,这就是一个有序数组[2, 5, 13],求从后到前的累加数组,也就是[20, 18, 13],是不是感觉这就简单了。
为什么变成数组就是感觉简单了呢?
因为数组大家都知道怎么遍历啊,从后向前,挨个累加就完事了,这换成了二叉搜索树,看起来就别扭了一些是不是。
那么知道如何遍历这个二叉树,也就迎刃而解了,从树中可以看出累加的顺序是右中左,所以我们需要反中序遍历这个二叉树,然后顺序累加就可以了。
本题依然需要一个pre指针记录当前遍历节点cur的前一个节点,这样才方便做累加
二叉搜索树 pre指针的使用技巧,参考501.二叉搜索树中的众数
二叉搜索树中的众数 530.搜索树最小绝对差
# 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: Optional[TreeNode]) -> Optional[TreeNode]:
pre = TreeNode()
def rec(root):
nonlocal pre
if not root:
return None
rec(root.right) #右
root.val = root.val + pre.val #中
pre = root
rec(root.left) #左
rec(root)
return root
等二刷复习的时候 直接先看这篇
二叉树总结篇