Given a binary tree, determine if it is a valid binary search tree (BST).
Assume a BST is defined as follows:
- The left subtree of a node contains only nodes with keys less than the node's key.
- The right subtree of a node contains only nodes with keys greater than the node's key.
- Both the left and right subtrees must also be binary search trees.
Example 1:
2 / \ 1 3Binary tree
Example 2:
1 / \ 2 3Binary tree
<Solution>
這題要來確認 input 給的 BST 是不是符合規則的
看個例子
5
/ \
3 8
/ \ / \
0 4 6 10
先注意到一點,題目規範的 BST 是不會有重複元素出現的,只有大於小於,沒有等於的問題
因此,可以用 inorder traversal 來歷遍每個 node,並檢查是否符合遞增數列的走向
因為每個 subtree 都也要符合題目BST的規則,所以用 inorder traversal 來看,output會是一個遞增數列
0 3 4 5 6 8 10
code 如下(參考資料)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Definition for a binary tree node. | |
* struct TreeNode { | |
* int val; | |
* TreeNode *left; | |
* TreeNode *right; | |
* TreeNode(int x) : val(x), left(NULL), right(NULL) {} | |
* }; | |
*/ | |
class Solution { | |
public: | |
bool isValidBST(TreeNode* root) { | |
//> use inorder to traverse BST | |
//> the output should be increasing order | |
vector<int> prevNum; | |
TreeNode *curr = root; | |
stack<TreeNode *> nodeStack; | |
while(curr || !nodeStack.empty()) { | |
while(curr) { | |
nodeStack.push(curr); | |
curr = curr->left; | |
} | |
curr = nodeStack.top(); | |
nodeStack.pop(); | |
if(prevNum.empty()) { | |
prevNum.push_back(curr->val); | |
} | |
else { | |
//> must in increasing order | |
if(curr->val <= prevNum[0]) { | |
return false; | |
} | |
else { | |
prevNum[0] = curr->val; | |
} | |
} | |
curr = curr->right; | |
} | |
return true; | |
} | |
}; |
看到別人也有遇到同樣問題,所以就先放棄 morris traversal 的解法
這邊還有一種想法,是利用 BST 的本質,就是 left node < root node < right node
利用這個本質特性,搭配遞迴去檢查 left subtree 和 right subtree,來看整個 tree 是否是合法的 BST
這邊使用 long 來存放最大最小值,是為了包含 int 的最大最小值的邊界檢查
code 如下
c++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Definition for a binary tree node. | |
* struct TreeNode { | |
* int val; | |
* TreeNode *left; | |
* TreeNode *right; | |
* TreeNode(int x) : val(x), left(NULL), right(NULL) {} | |
* }; | |
*/ | |
class Solution { | |
public: | |
bool isValidBST(TreeNode* root) { | |
return checkValidBST(root, LONG_MIN, LONG_MAX); | |
} | |
bool checkValidBST(TreeNode *root, const long &minVal, const long &maxVal) { | |
if(!root) { | |
return true; | |
} | |
else if(root->val <= minVal || root->val >= maxVal) { | |
return false; | |
} | |
//> check left subtree and right subtree | |
return checkValidBST(root->left, minVal, root->val) && checkValidBST(root->right, root->val, maxVal); | |
} | |
}; |
kotlin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Example: | |
* var ti = TreeNode(5) | |
* var v = ti.`val` | |
* Definition for a binary tree node. | |
* class TreeNode(var `val`: Int) { | |
* var left: TreeNode? = null | |
* var right: TreeNode? = null | |
* } | |
*/ | |
class Solution { | |
fun isValidBST(root: TreeNode?): Boolean { | |
return valid(root, Long.MIN_VALUE, Long.MAX_VALUE) | |
} | |
fun valid(node: TreeNode?, minValue: Long, maxValue: Long): Boolean { | |
return when { | |
node == null -> true | |
node!!.`val` <= minValue || node!!.`val` >= maxValue -> false | |
else -> { | |
valid(node!!.left, minValue, node!!.`val`.toLong()) | |
&& valid(node!!.right, node!!.`val`.toLong(), maxValue) | |
} | |
} | |
} | |
} |
沒有留言:
張貼留言