1、Leetcode之验证二叉搜索树(98)
题目描述:
【中等题】
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。
题目链接
思路分析
题解一:递归+最大值最小值思想
1、根据二叉搜索树的性质可知每一个结点(可设根结点位于 ( − inf , + inf ) (-\inf ,+\inf) (−inf,+inf)都位于一个区间范围内,则我们可借助一个辅助函数进行递归,判断此数是否为BST。下面为辅助函数的构造:
2、定义结点是否在区间范围辅助函数:
- 如果树为空,则返回True
- 如果根结点不位于【正无穷,负无穷】之间,返回False
- 递归调用左子树【由于左子树结点小于根结点,所以上界为根结点值】和右子树【由于右子树结点大于根结点值,所以下界为根结点值】
- 返回函数之左子树和右子树的且值。
3、返回根结点的辅助函数值
【python3代码实现】
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
def temp(root:TreeNode,min_val:float,max_val:float)->bool:
if not root:
return True
if not min_val<root.val<max_val:
return False
return temp(root.left,min_val,root.val) and temp(root.right,root.val,max_val)
return temp(root,float('-inf'),float('inf'))
-
时间复杂度 : O ( n ) O(n) O(n),其中 n 为二叉树的节点个数。在递归调用的时候二叉树的每个节点最多被访问一次。
-
空间复杂度 : O ( n ) O(n) O(n),其中 n 为二叉树的节点个数。递归函数在递归过程中需要为每一层递归函数分配栈空间,所以这里需要额外的空间且该空间取决于递归的深度,即二叉树的高度。最坏情况下二叉树为一条链,树的高度为 nn ,递归最深达到n 层,故最坏情况下空间复杂度为 O ( n ) O(n) O(n)。
题解二:迭代之中序遍历
1、二叉搜索树的中序遍历是一个递增序列,因此,我们可以在中序遍历中,通过判断前一结点值是否小于当前这一节点值这一条件来判断是否为BST。
2、可将前一节点初始化为负无穷,判断条件是加在访问根结点之后。
【python3 代码实现】
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
stack=[]
inorder=float('-inf')#初始化前一节点值为负无穷
while stack or root:
while root:
stack.append(root)
root=root.left
root=stack.pop()
# 如果中序遍历得到的节点的值小于前一节点值,则说明不是二叉搜索树
if root.val<=inorder:
return False
inorder=root.val#更新前一节点值
root=root.right
return True
-
时间复杂度 : O ( n ) O(n) O(n),其中 n 为二叉树的节点个数。
-
空间复杂度 : O ( n ) O(n) O(n),其中 n 为二叉树的节点个数。栈最多存储n个结点,因此需要额外的 O ( n ) O(n) O(n)的空间。
2、二叉搜索树迭代器(173)
题目描述:
【中等题】
实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。
调用 next() 将返回二叉搜索树中的下一个最小的数。
思路分析
1、题目是要求我们建立一个遍历二叉树的迭代器,含有next()
和 hasNext()
两个函数。hasNext()
函数的作用是:返回一个布尔值,表示二叉搜索树中是否还有元素。next()
函数返回二叉搜索树中下一个最小元素。因此,我们第一次调用 next()
函数时,应返回二叉搜索树中的最小元素;同理,当我们最后一次调用 next()
时,应返回二叉搜索树中的最大元素。
2、利用二叉搜索树的中序遍历为递增序列这一性质,可以采用进栈出栈的方式实现next()
函数,hasNext()
函数只需要判断栈是否为空即可实现。
3、实现next()
函数:我们知道最左值一定是最小值。我们只需要将左边不断压栈,那么栈中存放的就是从大到小的值。调用next的时候,我们只需要弹出栈顶元素即可,同时我们需要将right加入栈中(非递归先序遍历二叉树的思路)。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class BSTIterator:
def __init__(self, root):
"""
:type root: TreeNode
"""
self.stack = list()
self.pushLeft(root)
def next(self):
"""
@return the next smallest number
:rtype: int
"""
node = self.stack.pop()
self.pushLeft(node.right)
return node.val
#它将给定节点中的所有左子节点添加到栈中,直到节点没有左子节点为止。
def pushLeft(self, node):
while node:
self.stack.append(node)
node = node.left
def hasNext(self):
"""
@return whether we have a next smallest number
:rtype: bool
"""
return True if self.stack else False