【leetcode】二叉树刷题总结(三)二叉搜索树问题

二叉搜索树特性问题

LeetCode700题 二叉树搜索树中的搜索

利用二叉搜索树特性,将搜索复杂度降为logn

# 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 searchBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if root is None:
            return None
        elif val == root.val:
            return root
        elif val > root.val:
            return self.searchBST(root.right, val)
        elif val < root.val:
            return self.searchBST(root.left, val)

LeetCode230题 二叉树搜索树中第k小的元素

利用中序遍历有序性特点,记录中序遍历过的节点数,满足k次就停止遍历,记录结果

如果想实现logn的时间复杂度算法,每个节点需要记录自己的排名,这样就可以利用二叉搜索树特性解题

# 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 kthSmallest(self, root: Optional[TreeNode], k: int) -> int:
        self.res = None
        self.num = 0
        self.traversal(root, k)
        return self.res

    def traversal(self, root, k):
        if not root:
            return
        self.traversal(root.left, k)
        if self.num == k:
            return
        self.res = root.val
        self.num += 1
        self.traversal(root.right, k)

LeetCode501题 二叉搜索树中的众数

利用中序遍历有序性特点

# 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 findMode(self, root: Optional[TreeNode]) -> List[int]:
        self.res = []
        self.cur_count = 0
        self.last_val = float('-inf')
        self.max_count = float('-inf')
        self.traversal(root)
        return self.res
    
    def traversal(self, node):
        if node is None:
            return
        self.traversal(node.left)
        if node.val == self.last_val:
            self.cur_count += 1
        else:
            self.cur_count = 1
            self.last_val = node.val
        if self.cur_count > self.max_count:
            self.max_count = self.cur_count
            self.res = [node.val]
        elif self.cur_count == self.max_count:
            self.res.append(node.val)
        self.traversal(node.right)

LeetCode530题 二叉搜索树的最小绝对差

利用中序遍历有序性特点,只需要计算相邻元素的差值即可

# 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 getMinimumDifference(self, root: Optional[TreeNode]) -> int:
        self.pre = None
        self.res = float('inf')
        self.traversal(root)
        return self.res

    def traversal(self, root):
        if root is None:
            return
        self.traversal(root.left)
        if self.pre is not None:
            self.res = min(self.res, root.val - self.pre)
        self.pre = root.val
        self.traversal(root.right)

LeetCode538题 把二叉树搜索树转换为累加树

利用中序遍历有序性特点,按照“右中左”遍历顺序遍历,记录累加和,将累加和,将累加和与当前节点值相加即可

# 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]:
        self.pre_sum = 0
        self.traversal(root)
        return root

    def traversal(self, root):
        if not root:
            return
        self.traversal(root.right)
        root.val += self.pre_sum
        self.pre_sum = root.val
        self.traversal(root.left)
        return

判断合法性、增、删问题

LeetCode98题 验证二叉搜索树

通过使用递归函数,增加函数参数列表,在参数中携带额外信息,将二叉搜索树的约束传递给子树的所有节点。(递归函数增加参数,可以让信息自顶向下传递;递归函数带返回值,可以让信息自底向上传递

遍历思路-递归法

# 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 isValidBST(self, root: Optional[TreeNode]) -> bool:
        return self.traversal(root, None, None)

    def traversal(self, root, min_node, max_node):
        # min_node表示以root为根的子树节点值下限,max_node表示以root为根的子树节点值上限,否则就不符合条件
        if not root:
            return True
        if min_node and root.val <= min_node.val:
            return False
        if max_node and root.val >= max_node.val:
            return False
        left = self.traversal(root.left, min_node, root)   
        right = self.traversal(root.right, root, max_node)
        return left and right

 LeetCode450题 删除二叉搜索树中的节点

分解思路-递归法

# 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 deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
        if not root:
            return
        if root.val < key:
            root.right = self.deleteNode(root.right, key)
        elif root.val > key:
            root.left = self.deleteNode(root.left, key)
        else:
            if not root.left:
                root = root.right
            elif not root.right:
                root = root.left
            else:
                cur = root.left
                while cur.right:
                    cur = cur.right
                cur.right = root.right
                root = root.left
        return root

 LeetCode669题 修剪二叉搜索树

分解思路-递归法

# 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:
            return self.trimBST(root.right, low, high)
        elif root.val > high:
            return self.trimBST(root.left, low, high)
        else:
            root.left = self.trimBST(root.left, low, high)
            root.right = self.trimBST(root.right, low, high)
        return root

LeetCode701题 二叉搜索树中的插入操作

分解思路-递归法

# 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 insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
        if not root:
            return TreeNode(val=val)
        if root.val > val:
            root.left = self.insertIntoBST(root.left, val)
        else:
            root.right = self.insertIntoBST(root.right, val)
        return root

 LeetCode1373题 二叉搜索子树的最大键值和

在后序位置自底向上判断是否是二叉搜索子树、返回子树节点值的和。在遍历过程中遇到符合条件的子树时,更新结果(本题和“验证二叉搜索树”有点类似,但“验证二叉搜索树”解法采用自顶向下传递信息的方式判断)

# 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 maxSumBST(self, root: Optional[TreeNode]) -> int:
        self.res = 0
        self.traversal(root)
        return self.res

    def traversal(self, root):
        # 返回以root为根节点子树的节点和、子树最小值、最大值,若root不是二叉搜索树全部返回None
        if not root:
            return 0, float('inf'), float('-inf')
        left_sum, left_min, left_max = self.traversal(root.left)
        right_sum, right_min, right_max = self.traversal(root.right)
        if left_sum is not None and right_sum is not None and root.val > left_max and root.val < right_min:
            r = left_sum + right_sum + root.val
            self.res = max(self.res, r)
            return r, min(left_min, root.val), max(right_max, root.val)
        else:
            return None, None, None

构造问题

LeetCode108题 将有序数组转换为二叉搜索树

分解思路-递归法

# 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
        mid = len(nums) // 2
        root = TreeNode(val=nums[mid])
        root.left = self.sortedArrayToBST(nums[:mid])
        root.right = self.sortedArrayToBST(nums[mid + 1:])
        return root

LeetCode96题 不同的二叉搜索树

动态规划

class Solution:
    def numTrees(self, n: int) -> int:
        dp = [1] * (n + 1)
        for i in range(2, n + 1):
            r = 0
            for j in range(1, i + 1):
                r += dp[j - 1] * dp[i - j]
            dp[i] = r
        return dp[n]

LeetCode95题 不同的二叉搜索树II

递归函数返回值设计为 以[start:end]区间中的数组成的二叉搜索树根节点,在后序位置组合左右子树的根节点 作为不同的二叉搜索树结果

# 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 generateTrees(self, n: int) -> List[Optional[TreeNode]]:
        return self.traversal(1, n)

    def traversal(self, start, end):
        # 返回以[start:end]区间中的数组成的二叉搜索树根节点
        if start > end:
            return [None]
        res = []
        for i in range(start, end + 1):
            left = self.traversal(start, i - 1)
            right = self.traversal(i + 1, end)
            for j in left:
                for k in right:
                    root = TreeNode(val=i)
                    root.left = j
                    root.right = k
                    res.append(root)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值