-
Notifications
You must be signed in to change notification settings - Fork 0
98. Validate Binary Search Tree #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
Solve Time: 18:52 | ||
|
||
Time: O(N^2) | ||
Space: O(N) | ||
|
||
最初、部分木の最大値/最小値の算出とBST判定を同時にやろうとしてハマりかけたのでそれぞれの判定を関数に切り出してシンプルにした | ||
同時にいろんなことをしようとすると、書くのも読むのも大変なコードになりそう、というかそういうコードを考えること自体が負荷だった | ||
|
||
*/ | ||
class Solution { | ||
public: | ||
bool isValidBST(TreeNode* root) { | ||
if (!root) { | ||
return true; | ||
} | ||
if (!isValidBST(root->left) || !isValidBST(root->right)) { | ||
return false; | ||
} | ||
if (root->left && max_val_in_tree(root->left) >= root->val) { | ||
return false; | ||
} | ||
if (root->right && min_val_in_tree(root->right) <= root->val) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
private: | ||
int max_val_in_tree(TreeNode* root) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分は関数名は UpperCamel で書くことが多いです。 https://google.github.io/styleguide/cppguide.html#Function_Names
|
||
int max_val = root->val; | ||
if (root->left) { | ||
max_val = max(max_val, max_val_in_tree(root->left)); | ||
} | ||
if (root->right) { | ||
max_val = max(max_val, max_val_in_tree(root->right)); | ||
} | ||
return max_val; | ||
} | ||
|
||
int min_val_in_tree(TreeNode* root) { | ||
int min_val = root->val; | ||
if (root->left) { | ||
min_val = min(min_val, min_val_in_tree(root->left)); | ||
} | ||
if (root->right) { | ||
min_val = min(min_val, min_val_in_tree(root->right)); | ||
} | ||
return min_val; | ||
|
||
} | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
Time: O(N) | ||
Space: O(N) | ||
|
||
下限と上限を持って再帰を構築する。 | ||
step1でこういった解法に思い至れなかったのは、関数を分けるという発想が出来ず | ||
同時に複数のことを一つの関数でやろうとして混乱していた | ||
思考中に負荷を感じたら何らかを分割するみたいな考え方が必要そう | ||
*/ | ||
class Solution { | ||
public: | ||
bool isValidBST(TreeNode* root) { | ||
if (!root) { | ||
return true; | ||
} | ||
return is_valid_bst_recursive(root, numeric_limits<int64_t>::min(), numeric_limits<int64_t>::max()); | ||
} | ||
|
||
private: | ||
bool is_valid_bst_recursive(TreeNode* node, int64_t left_val, int64_t right_val) { | ||
if (!node) { | ||
return true; | ||
} | ||
if (!(left_val < node->val && node->val < right_val)) { | ||
return false; | ||
} | ||
return is_valid_bst_recursive(node->left, left_val, node->val) && is_valid_bst_recursive(node->right, node->val, right_val); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1 行がやや長いように感じました。定義改行を入れるとよいと思います。 |
||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
Time: O(N) | ||
Space: O(N) | ||
|
||
in-order走査でvalがソートされるBSTの性質を利用した解法 | ||
|
||
*/ | ||
class Solution { | ||
public: | ||
bool isValidBST(TreeNode* root) { | ||
if (!root) { | ||
return true; | ||
} | ||
vector<int> sorted_vals; | ||
stack<TreeNode*> in_order_operating_nodes; | ||
in_order_operating_nodes.push(root); | ||
while (in_order_operating_nodes.top()->left) { | ||
in_order_operating_nodes.push(in_order_operating_nodes.top()->left); | ||
} | ||
while (!in_order_operating_nodes.empty()) { | ||
auto node = in_order_operating_nodes.top(); | ||
in_order_operating_nodes.pop(); | ||
sorted_vals.push_back(node->val); | ||
if (node->right) { | ||
in_order_operating_nodes.push(node->right); | ||
while (in_order_operating_nodes.top()->left) { | ||
in_order_operating_nodes.push(in_order_operating_nodes.top()->left); | ||
} | ||
} | ||
} | ||
for (int i = 0; i < sorted_vals.size() - 1; ++i) { | ||
if (sorted_vals[i] >= sorted_vals[i+1]) { | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この判定、push_back のところでできませんか。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 下でしてましたね。 |
||
} | ||
} | ||
return true; | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
Time: O(N) | ||
Space: O(N) | ||
|
||
in-order走査のメモリ改良版 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inorderの解法は再帰関数で書いてましたが、スタックでも解けるんですね。勉強になりました。 |
||
|
||
*/ | ||
class Solution { | ||
public: | ||
bool isValidBST(TreeNode* root) { | ||
if (!root) { | ||
return true; | ||
} | ||
stack<TreeNode*> in_order_operating_nodes; | ||
in_order_operating_nodes.push(root); | ||
TreeNode* checking_node; | ||
int64_t under_limit = numeric_limits<int64_t>::min(); | ||
while (in_order_operating_nodes.top()->left) { | ||
in_order_operating_nodes.push(in_order_operating_nodes.top()->left); | ||
} | ||
while (!in_order_operating_nodes.empty()) { | ||
auto node = in_order_operating_nodes.top(); | ||
in_order_operating_nodes.pop(); | ||
if (under_limit >= node->val) { | ||
return false; | ||
} | ||
under_limit = node->val; | ||
if (node->right) { | ||
in_order_operating_nodes.push(node->right); | ||
while (in_order_operating_nodes.top()->left) { | ||
in_order_operating_nodes.push(in_order_operating_nodes.top()->left); | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class Solution { | ||
public: | ||
bool isValidBST(TreeNode* root) { | ||
return is_valid_bst_recursive(root, numeric_limits<int64_t>::min(), numeric_limits<int64_t>::max()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -2^31 <= Node.val <= 2^31 - 1 の制約を受けて int64_t型を使っているかと思うのですが、もう一つのmin/max対策として、*intのようなポインタ型を使ってnull判定をする方法もあります。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
コメントありがとうございます。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Go言語のコードですが、こんな感じです。 func isValidBST(root *TreeNode) bool {
return isValidBSTRecursively(root, nil, nil)
}
func isValidBSTRecursively(node *TreeNode, lowerBound, upperBound *int) bool {
if node == nil {
return true
}
if lowerBound != nil && node.Val <= *lowerBound {
return false
}
if upperBound != nil && node.Val >= *upperBound {
return false
}
return isValidBSTRecursively(node.Left, lowerBound, &node.Val) && isValidBSTRecursively(node.Right, &node.Val, upperBound)
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 共有ありがとうございます。 |
||
} | ||
|
||
private: | ||
bool is_valid_bst_recursive(TreeNode* node, int64_t under_limit, int64_t upper_limit) { | ||
if (!node) { | ||
return true; | ||
} | ||
if (node->val <= under_limit || upper_limit <= node->val) { | ||
return false; | ||
} | ||
return is_valid_bst_recursive(node->left, under_limit, node->val) && | ||
is_valid_bst_recursive(node->right, node->val, upper_limit); | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
「ペアを返す再帰にすると線形時間になる」ですね。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.r1pr4pvhjsjx