以下為我的天梯積分規則:
每日至少一題:一題積分+10分
若多做了一題(或多一種方法解答),則當日積分+20分(+10+10)
若做了三道以上,則從第三題開始算+20分(如:做了三道題則積分-10+10+20=40;做了四道題則積分–10+10+20+20=60)
初始分為100分
若差一天沒做題,則扣積分-10分(周六、周日除外注:休息)
堅持!!!
初級算法
刷題目錄
連結清單
題幹
給你一個
二叉樹的根節點 root ,判斷其是否是一個有效的
二叉搜尋樹。
有效 二叉搜尋樹定義如下:
- 節點的左子樹隻包含 小于 目前節點的數。
- 節點的右子樹隻包含 大于 目前節點的數。
- 所有左子樹和右子樹自身必須也是二叉搜尋樹。
示例 1:
輸入:root = [2,1,3]
輸出:true
示例2:
輸入:root = [5,1,4,null,null,3,6]
輸出:false
解釋:根節點的值是 5 ,但是右子節點的值是 4 。
提示:
樹中節點數目範圍在[1, 10^4] 内
-2^31 <= Node.val <= 2^31 - 1
中序周遊
分析:
可能由讀者不知道中序周遊是什麼,我們這裡簡單提及一下,中序周遊是二叉樹的一種周遊方式,它先周遊左子樹,再周遊根節點,最後周遊右子樹。而我們二叉搜尋樹保證了左子樹的節點的值均小于根節點的值,根節點的值均小于右子樹的值,是以中序周遊以後得到的序列一定是升序序列。(引用自了力扣原始解釋,這個解釋很通透!)
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
if not root:
return True
prev = None
stack = []
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
# 若中序周遊得到的節點的值小于前一個值prev,那麼就說明不是二叉搜尋樹,傳回False
if prev and root.val <= prev.val:
return False
# 儲存上一節點
prev = root
root = root.right
return True
這個速度超級快,超過100%!!!
思路很不錯!!!多多練習
搜尋(遞歸)
有大佬分析的很透徹,來看下面的圖
注意6這個節點不光要小于15而且還要大于10,是以這裡的每一個節點都是有一個範圍的。這裡我們來給每個節點添加一個範圍,如果不在這個範圍之内直接傳回false,比如6的範圍是(10,15),很明顯他不在這個範圍内,是以他不是
。下面方法可能不完全按照上面解釋一緻。
class Solution:
prev = None # 用于記錄前一個節點
def isValidBST(self, root: TreeNode) -> bool:
if not root:
return True
# 從左開始遞歸
if not self.isValidBST(root.left):
return False
# 判斷前一節點是否大于目前
if self.prev is not None and self.prev.val >= root.val:
return False
# 儲存前個節點
self.prev = root
# 右邊遞歸
if not self.isValidBST(root.right):
return False
return True
增加上下界的寫法:
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
# 遞歸并引入上界,下界來判斷是否有效的二叉搜尋樹
def chesh(node, min_val = float('-inf'), max_val = float('inf')) -> bool:
if not node:
return True
#每個節點如果超過這個範圍,直接傳回false,設定出口
if node.val <= min_val or node.val >= max_val:
return False
#這裡再分别以左右兩個子節點分别判斷
#左子樹範圍的最小值是minVal,最大值是目前節點的值,也就是root的值,因為左子樹的值要比目前節點小
#右子數範圍的最大值是maxVal,最小值是目前節點的值,也就是root的值,因為右子樹的值要比目前節點大
return chesh(node.left, min_val, node.val) and chesh(node.right, node.val, max_val)
return chesh(root)
複現大佬的Java代碼。