LeetCode Medium 98 驗證二叉搜尋樹 Python
阿新 • • 發佈:2019-01-13
def isValidBST(self, root): """ My Method 2 Solution Method 也是這個思路 演算法:遞迴 思路: 在遞迴的過程中判斷左右是否滿足要求 遞迴的時候用min_border和 max_border記錄當前位置最小不能小於多少,最大不能大於多少 左側節點應該小於當前根節點,但是不能小於min_border,比如下面的這個3,3小於4,但是3不應該小於5 同理,右側節點的值應該大於當前根節點,但是不能大於最大的max_border 5 / \ 1 4 / \ 3 6 往左子樹傳的時候,更新最大上界為root.val,最小上界不變,往右子樹傳的時候更新最小上界為root.val,最大上界不變 所以向下傳的時候,向左側傳的話,就會更新max_border為root.val 左子樹中的值再小也不能小於min_border 同理,向右子樹傳的時候,更新min_border 為root.val,右子樹中的值再大也不能大於max_border,二者是交替的, 然後更新min的時候max保持不變 3是4的左子樹,3小於4,但是再小也不能小於5,min_border是上一層的root.val = 5 在最一開始的時候,上下界是沒關係的,可以認為是正負無窮,所以傳inf 複雜度: 時間:OK,第K個節點是不滿足條件的話,停止 空間:OK,遞迴棧空間 """ def check_valid(root, min_border, max_border): if root == None: return True if root.left == None and root.right == None: return True left_check = right_check = True if root.left != None: if root.left.val >= root.val or root.left.val <= min_border: return False else: left_check = check_valid(root.left, min_border, root.val) if root.right != None: if root.right.val <= root.val or root.right.val >= max_border: return False else: right_check = check_valid(root.right, root.val, max_border) return left_check and right_check return check_valid(root, float('-inf'), float('inf')) def isValidBST_bfs(self, root): """ Solution Method 2 將 DFS轉為BFS,用佇列按層遍歷,剩下的思路和上面是一樣的 用棧也行,只不過用棧的話先壓右子樹再壓左子樹,這樣訪問的時候就是左右了 訪問當前節點為root構成的子樹時。要確認root,root.left.val,root.right.val的值的狀態,每個root 處都有一個lower_limit和upper_limit,所以用佇列/棧按層訪問也是一樣的,畢竟相當於是判斷一個區域性狀態 """ if not root: return True queue = [(root, None, None), ] while queue: root, lower_limit, upper_limit = queue.pop(0) if root.left: if root.left.val < root.val: if lower_limit and root.left.val <= lower_limit: return False queue.append((root.left, lower_limit, root.val)) else: return False if root.right: if root.right.val > root.val: if upper_limit and root.right.val >= upper_limit: return False queue.append((root.right, root.val, upper_limit)) else: return False return True def isValidBST1(self, root): """ My Naive Method 演算法:遍歷 思路: 很樸素的思路,利用二叉搜尋樹的特性,中序遍歷得到的序列一定是有序序列,所以我就中序遍歷一次,得到 值的列表result 然後再遍歷result檢查,如果result不是有序陣列的話,就說明Tree一定不是一顆二叉搜尋樹 其實效率還可以,遍歷一次所有的節點ON,然後檢查陣列也是ON,總體的時間是ON 複雜度分析: 時間:ON 空間:ON """ result = [] def inorder(root): if root == None: return inorder(root.left) result.append(root.val) inorder(root.right) inorder(root) if len(result) in (0, 1): return True for i in range(1, len(result)): if result[i] <= result[i - 1]: return False return True