leetcode 98題
給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。
假設乙個二叉搜尋樹具有如下特徵:
節點的左子樹只包含小於當前節點的數。必然從二叉搜尋樹的特性出發。容易知道,二叉搜尋樹的中序遍歷是乙個遞增的陣列。所以最簡單的方法就是對其進行中序遍歷,並看是否是遞增的。節點的右子樹只包含大於當前節點的數。
所有左子樹和右子樹自身必須也是二叉搜尋樹。
class
solution
return
true;}
public
void
inorder
(treenode root)
}
這種方法的缺點,第一是需要乙個o(n)
的空間來儲存中序遍歷的結果;第二是如果遍歷過程中已經發現不滿足二叉搜尋樹的情況了,其實可以直接退出,但是它要第二次遍歷時才會退出。
對中序遍歷的方法進行略微修改即可。由於中序遍歷是按照從小到大的順序的,所以只要當前值小於或等於前乙個的值,那麼就必然是false
。所以用pre
記錄前乙個的值即可,但是要注意pre
的初始化。
class
solution
public
boolean
inorder
(treenode root)
// 當前 value 變成pre value
pre = cur;
boolean r =
inorder
(root.right)
;// 必須滿足兩側都是搜尋樹
return l && r;
}}
對pre
用long
來初始化,因為測試用例中有integer.min_value
,所以如果pre
也是integer.min_value
的話,無法大於它。
思想同理,用指標和堆疊實現二叉樹的非遞迴中序遍歷。不過效率居然比第二個要低,不知道為什麼。
class
solution
else
}return
true;}
}
在leetcode上,很多人的解法是從界限出發的。因為左子樹的值都是小於root的,右子樹的值都是大於root的,所以左側的範圍就是(min,root.val)
,右側的範圍是(root.val,max)
。但是要注意邊界的問題,到底有沒有等號。
不過這種思路並沒有利用到二叉搜尋樹的中序遍歷是有序的這個特性。
class
solution
public
boolean
isvalidbst
(treenode root,
long min,
long max)
// 由於(*),所以這裡不需要root.val+1或者-1
return
isvalidbst
(root.left,min,root.val)
&&isvalidbst
(root.right,root.val,max);}
}
驗證二叉搜尋樹
題目 給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 1 3 輸出 true 示例 2 輸入 5 1 4 3 6 輸出 false ...
驗證二叉搜尋樹
給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 1 3 輸出 true示例 2 輸入 5 1 4 3 6 輸出 false 解釋 輸...
驗證二叉搜尋樹
給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 1 3輸出 true 示例 2 輸入 5 1 4 3 6輸出 false 解釋 輸入...