98验证二叉搜索树
题目: 给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:1节点的左子树只包含小于当前节点的数 2 节点的右子树只包含大于当前节点的数 3 所有左子树和右子树自身必须也是二叉搜索树
来源: https://leetcode-cn.com/problems/validate-binary-search-tree/
法一: 官网递归方法
思路: 解题前先判断题目与二叉树的遍历方式有无关系,如果有关要先识别该用哪种遍历方法求解.必须要先画一个二叉树的图,对每个节点的范围标定后进行观察可发现,每个节点往下走的时候,如果是向右走,则该节点的值作为右子树区间的左端点.如果向左走,则该节点的值作为左子树区间的右端点.观察出规律来,还要用递归实现.
# 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): def helper(node, lower=float('-inf'), upper=float('inf')): # 如果节点为空,则返回True if not node: return True val = node.val # 根节点的范围是-inf到inf,先用这两个来确定范围,也为了方便后续的传参 # 如果不在这个范围内,则返回False if val <= lower or val >= upper: return False # 先递归右子树, if not helper(node.right, val, upper): return False # 再递归左子树 if not helper(node.left, lower, val): return False return True return helper(root) if __name__ == '__main__': duixiang = Solution() root = TreeNode(8) a = TreeNode(4) b = TreeNode(9) root.left = a root.right = b al = TreeNode(3) ar = TreeNode(6) a.left = al a.right = ar arl = TreeNode(5) arr = TreeNode(7) ar.left = arl ar.right = arr a = duixiang.isValidBST(root) print(a)
法二: 利用了二叉树中序遍历最经典的迭代方法.
# 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): stack, inorder = [], float('-inf') while stack or root: while root: stack.append(root) root = root.left root = stack.pop() # 如果这里有res.append(root.val),则res中最后存储的即为二叉树的中序遍历, # inorder是上一个数,root.val是下一个数,如果下一个大于上一个了,则不是二叉搜索树,返回False if root.val <= inorder: return False inorder = root.val root = root.right return True if __name__ == '__main__': duixiang = Solution() root = TreeNode(8) a = TreeNode(4) b = TreeNode(9) root.left = a root.right = b al = TreeNode(3) ar = TreeNode(6) a.left = al a.right = ar arl = TreeNode(5) arr = TreeNode(7) ar.left = arl ar.right = arr a = duixiang.isValidBST(root) print(a)
法三: 自己参考官网解法后的代码
# Definition for a binary tree node. class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None # 执行用时 :48 ms, 在所有 python3 提交中击败了95.99% 的用户 # 内存消耗 :15.3 MB, 在所有 python3 提交中击败了99.64%的用户 class Solution: def isValidBST(self, root: TreeNode) -> bool: # res = [float('-inf')] stack = [] stack.append((root, 1)) while stack: x, sign = stack.pop() if x is None: continue # 这里用0标记被遍历过了,1表示没有遍历,如遍历过了则存储 # 否则继续遍历,一直朝左找到底 if sign: # 中序遍历 stack.append((x.right, 1)) stack.append((x, 0)) stack.append((x.left, 1)) else: # res中存储的是中序遍历 res.append(x.val) # 如果不成立,说明不是二叉树搜索树,直接返回False if res[-1] - res[-2] > 0: pass else: return False return True if __name__ == '__main__': duixiang = Solution() root = TreeNode(8) a = TreeNode(4) b = TreeNode(9) root.left = a root.right = b al = TreeNode(3) ar = TreeNode(6) a.left = al a.right = ar arl = TreeNode(5) arr = TreeNode(7) ar.left = arl ar.right = arr a = duixiang.isValidBST(root) print(a)
的