leetcode 98 验证二叉搜索树
给定一个二叉树,判断其是否是一个有效的二叉搜索树。
假设一个二叉搜索树具有如下特征:
1.节点的左子树只包含小于当前节点的数。
2.节点的右子树只包含大于当前节点的数。
3.所有左子树和右子树自身必须也是二叉搜索树。
示例:
解题思路:
解法一:使用中序遍历,得到的数组是升序的,优化方法是判断当前节点大于前继节点即可。检查 inorder中的每个元素是否小于下一个
解法二:递归法。递归返回需要传出两个值,对于左子树找到最大值返回a,对于右子树找到最小值返回b,那么root要大于a, 且root小于b,就可以继续往下循环,直到所有节点满足这个即可。
两
种
解
法
都
是
只
会
访
问
节
点
一
次
,
所
以
时
间
复
杂
度
都
为
O
(
N
)
\color{blue}两种解法都是只会访问节点一次,所以时间复杂度都为O(N)
两种解法都是只会访问节点一次,所以时间复杂度都为O(N)
代码思路:
解法一:
第一个写法是比较直接的,就是按照中序遍历的方式获取数组,若是升序,与排序后的数组相同,证明是二叉搜索树。 不过缺点是inorder的函数需要开辟新的空间,空间复杂度比较高。
第二个写法就做了一下优化,我们不需要保留整个数组下来,只需保存前继节点就可以,然后当前节点和前继节点比较即可。helper其实就是实现了中序遍历,
解法二:
倒数第三局,max代表上界,min代表下界,如果超出界外,就不对了. 不要误会成上面的解题思路的最大值a和最小值b,我自己回头看就看晕了~~
重点关注倒数第二句,看左子树时,无论你后面的值怎样,都要小于当前节点的,所以更改上界为root.val。看右子树是同理,当前节点要小于右子树所有节点,更新下界.
代码:
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
inorder = self.inorder(root)
return inorder == list(sorted(set(inorder)))
def inorder(self,root):
if root is None:
return []
return self.inorder(root.left)+[root.val]+self.inorder(root.right)
---------------------------------------------------------------------
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
self.prev = None
return self.helper(root)
def helper(self,root):
if root is None:
return True
if not self.helper(root.left): # 左子树
return False
if self.prev and self.prev.val >= root.val: #如果前一个数大于后一个,错误
return False
self.prev = root #跟换root为前一个结点
return self.helper(root.right) #右子树
解法二:
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
def isBST(root, min_val, max_val):
if root == None:
return True
# print(root.val)
if root.val >= max_val or root.val <= min_val:
#max代表上界,min代表下界,如果超出界外,就不对了
return False
return isBST(root.left, min_val, root.val) and isBST(root.right, root.val, max_val)
return isBST(root, float("-inf"), float("inf")) #正负无穷
复 杂 度 分 析 : \color{red}{复杂度分析:} 复杂度分析:
时间复杂度 : O(N)。每个结点访问一次。
空间复杂度 : O(N)。我们跟进了整棵树。