【二叉搜索树】(一) 二叉树搜索简介

目录

一、二叉搜索树的定义

二、验证二叉搜索树

2.1 题目要求

2.2 解决过程

三、二叉搜索树迭代器

3.1 题目要求

3.2 解决过程


一、二叉搜索树的定义

参考文献:https://leetcode-cn.com/leetbook/read/introduction-to-data-structure-binary-search-tree/xp6fkc/


二、验证二叉搜索树

2.1 题目要求

2.2 解决过程

官方实现与说明

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        """
        type root: TreeNode
        rtype: bool
        """
        def helper(node, lower = float('-inf'), upper = float('inf')):
            if not node:
                return True
            
            val = node.val
            if val <= lower or val >= upper:  # 节点值超界, 该子树不为BST
                return False
            if not helper(node.right, val, upper):  # 右子树不为BST, 整棵树不为BST
                return False
            if not helper(node.left, lower, val):  # 左子树不为BST, 整棵树不为BST
                return False
            return True  # 所有节点值正常, 该子树为BST

        return helper(root)

2020/07/31 - 99.95% (32ms) - 最佳

Pythonic 简化

class Solution:
    def isValidBST(self, root):

        def dfs(root, left, right):
            if not root:
                return True
            if left < root.val < right:  # 符合 BST 条件, 继续递归判断
                return dfs(root.left, left, root.val) and dfs(root.right, root.val, right)
            else:
                return False
        
        return dfs(root, float("-INF"), float("+INF"))


class Solution:
    def isValidBST(self, root):
        """
        type root: TreeNode
        rtype: bool
        """
        stack, inorder = [], float('-inf')
        
        # 中序遍历递归实现
        while stack or root:
            # 所有左子节点入栈
            while root:
                stack.append(root)  
                root = root.left
            # 首先是最左叶子节点, 然后是其父节点、祖父节点...
            root = stack.pop()  
            # 如果中序遍历得到的节点的值小于等于前一个 inorder, 说明不是二叉搜索树
            if root.val <= inorder:
                return False
            inorder = root.val  # 更新中序遍历前一个节点 inorder
            root = root.right  # 更新中序遍历节点

        return True

2020/07/32 - 53.01% (60ms)

 参考文献

https://leetcode-cn.com/leetbook/read/introduction-to-data-structure-binary-search-tree/xpkc6i/

https://leetcode-cn.com/problems/validate-binary-search-tree/solution/yan-zheng-er-cha-sou-suo-shu-by-leetcode-solution/


三、二叉搜索树迭代器

3.1 题目要求

3.2 解决过程

树节点定义

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

个人实现

法一:朴素法。先中序遍历二叉搜索树,将节点中序记录在列表中,然后通过指针与索引等方式直接查找和对比,返回结果。空间复杂度 O(n),时间复杂度 O(n)。

2020/07/31 - 69.17% (108ms)

class BSTIterator:
    def __init__(self, root: TreeNode):
        self.root = root  # 根节点
        self.seq = []  # 初始化中序遍历序列

        self._inorder(root)  # 记录中序遍历到序列中
        self.ptr = 0  # 当前指针
        self.num = len(self.seq)  # 节点总数

    def _inorder(self, node):
        """ non-public nested function for inorder traversal """
        if node:
            self._inorder(node.left)
            self.seq.append(node)
            self._inorder(node.right)

    def next(self) -> int:
        """  return the next smallest number """
        if self.ptr < self.num:
            self.ptr += 1  # 指针进位
            return self.seq[self.ptr-1].val  # 返回节点值
        return None

    def hasNext(self) -> bool:
        """ return whether we have a next smallest number """
        return self.ptr < self.num

# Your BSTIterator object will be instantiated and called as such:
# obj = BSTIterator(root)
# param_1 = obj.next()
# param_2 = obj.hasNext()

官方实现与说明


# 同个人实现法一
class BSTIterator:
    def __init__(self, root: TreeNode):
        # Array containing all the nodes in the sorted order
        self.nodes_sorted = []
        
        # Pointer to the next smallest element in the BST
        self.index = -1
        
        # Call to flatten the input binary search tree
        self._inorder(root)
        
    def _inorder(self, root):
        if not root:
            return
        self._inorder(root.left)
        self.nodes_sorted.append(root.val)
        self._inorder(root.right)

    def next(self) -> int:
        """
        @return the next smallest number
        """
        self.index += 1
        return self.nodes_sorted[self.index]

    def hasNext(self) -> bool:
        """
        @return whether we have a next smallest number
        """
        return self.index + 1 < len(self.nodes_sorted)


# 需要认真学习!
class BSTIterator:
    def __init__(self, root: TreeNode):
        # Stack for the recursion simulation
        self.stack = []
        
        # Remember that the algorithm starts with a call to the helper function
        # with the root node as the input
        self._leftmost_inorder(root)
        
    def _leftmost_inorder(self, root):
        # For a given node, add all the elements in the leftmost branch of the tree
        # under it to the stack.
        while root:
            self.stack.append(root)
            root = root.left

    def next(self) -> int:
        """
        @return the next smallest number
        """
        # Node at the top of the stack is the next smallest element
        topmost_node = self.stack.pop()
        
        # Need to maintain the invariant. If the node has a right child, call the 
        # helper function for the right child
        if topmost_node.right:
            self._leftmost_inorder(topmost_node.right)
        return topmost_node.val

    def hasNext(self) -> bool:
        """
        @return whether we have a next smallest number
        """
        return len(self.stack) > 0

2020/07/31 - 80.80% (104ms) 

参考文献

https://leetcode-cn.com/leetbook/read/introduction-to-data-structure-binary-search-tree/xpg4qe/

https://leetcode-cn.com/problems/binary-search-tree-iterator/solution/er-cha-sou-suo-shu-die-dai-qi-by-leetcode/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值