leetcode刷题记录:二叉搜索树

leetcode刷题记录:二叉搜索树

https://labuladong.online/algo/data-structure/bst-part1/

定义

  1. 对于任意一个节点node,左子树node小,右子树比node大
  2. 左右子树都是bst
    特性:中序遍历结果有序

1. 中序遍历

寻找第k小 https://leetcode.cn/problems/kth-smallest-element-in-a-bst/

class Solution(object):
    def kthSmallest(self, root, k):
        """
        :type root: TreeNode
        :type k: int
        :rtype: int
        """
        cur = root
        st = []
        idx = 0
        res = []
        while cur or st:
            if cur:
                st.append(cur)
                cur = cur.left
            else:
                cur = st.pop()
                res.append(cur.val)
                idx += 1
                if idx == k:
                    return cur.val
                cur = cur.right

BST转化为累加树

递归法反向中序遍(右中左),用一个全局变量记录sum

class Solution(object):
    def convertBST(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        def dfs(root):
            if not root:
                return
            dfs(root.right)
            root.val += self.total
            self.total = root.val
            dfs(root.left)
        self.total = 0
        dfs(root)
        return root

2. BST基本操作:判断合法性,增删查

判断BST的合法性

https://leetcode.cn/problems/validate-binary-search-tree/
迭代法中序遍历

class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        cur = root
        st = []
        prev = None
        while st or cur:
            while cur:
                st.append(cur)
                cur = cur.left
            cur = st.pop()
            # 注意,下面的if条件一定是if prev is not None, 而不是 if prev. 因为prev=0的时候,if prev = False
            if prev is not None and prev >= cur.val: 
                return False
            prev = cur.val
            cur = cur.right
        return True

寻找一个节点

https://leetcode.cn/problems/search-in-a-binary-search-tree/
二分搜索,很简单

class Solution(object):
    def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if not root:
            return root
        if root.val == val:
            return root
        elif root.val < val:
            return self.searchBST(root.right, val)
        else:
            return self.searchBST(root.left, val)

在BST中插入一个数

和查找一个数基本一样,稍微修改一下二分搜索的逻辑,接收递归的返回值

class Solution(object):
    def insertIntoBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if not root:
            return TreeNode(val)
        if root.val < val:
            root.right = self.insertIntoBST(root.right, val)
        elif root.val > val:
            root.left = self.insertIntoBST(root.left,val)
        return root

在BST中删除一个数

分情况讨论。

class Solution(object):
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """
        def findMin(root):
            while root and root.left:
                root = root.left
            return root
        if not root:
            return root
        if root.val > key:
            root.left = self.deleteNode(root.left, key)
        elif root.val < key:
            root.right = self.deleteNode(root.right, key)
        else:
            if not root.left:
                root = root.right
            elif not root.right:
                root = root.left
            else:
                # 注意传参,root.right 不是root
                minNode = findMin(root.right)
                # 注意传参,minNode.val 不是minNode,容易出错
                root.right = self.deleteNode(root.right, minNode.val) 
                minNode.left = root.left
                minNode.right = root.right
                root = minNode
        return root 

3. 构造

不同的二叉搜索树

穷举,用备忘录来消重。思路上非常简单,比dp容易想。
cuunt函数要传两个参数,缺点是memo是二维的,空间复杂度是O(n2)

class Solution(object):
    def numTrees(self, n):
        """
        :type n: int
        :rtype: int
        """
        def count(lo, hi):
            if lo > hi:
                return 1
            if self.memo[lo][hi] > 0:
                res = self.memo[lo][hi]
            else:
                res = 0
                for i in range(lo, hi+1):
                    res += count(lo, i-1) * count(i+1, hi)
                self.memo[lo][hi] = res
            return res
        self.memo = [[-1 for _ in range(n+1)] for _ in range(n+1)]
        return count(1, n)

不同的二叉搜索树 II

和I类似

class Solution(object):
    def generateTrees(self, n):
        """
        :type n: int
        :rtype: List[TreeNode]
        """
        def dfs(lo, hi):
            if lo > hi:
                return [None]
            res = []
            for i in range(lo, hi+1):
                leftTrees = dfs(lo, i-1)
                rightTrees = dfs(i+1, hi)
                for left in leftTrees:
                    for right in rightTrees:
                        root = TreeNode(i)
                        root.left = left
                        root.right = right
                        res.append(root)
            return res
        if n == 0:
            return []        
        return dfs(1, n)
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值