diff --git a/98/step1.cpp b/98/step1.cpp new file mode 100644 index 0000000..29d81d0 --- /dev/null +++ b/98/step1.cpp @@ -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) { + 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; + + } + }; + \ No newline at end of file diff --git a/98/step2_1.cpp b/98/step2_1.cpp new file mode 100644 index 0000000..1b9bc7c --- /dev/null +++ b/98/step2_1.cpp @@ -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::min(), numeric_limits::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); + } +}; diff --git a/98/step2_2.cpp b/98/step2_2.cpp new file mode 100644 index 0000000..6c659a4 --- /dev/null +++ b/98/step2_2.cpp @@ -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 sorted_vals; + stack 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; + } + } + return true; + } +}; diff --git a/98/step2_3.cpp b/98/step2_3.cpp new file mode 100644 index 0000000..0233ce2 --- /dev/null +++ b/98/step2_3.cpp @@ -0,0 +1,38 @@ +/* +Time: O(N) +Space: O(N) + +in-order走査のメモリ改良版 + +*/ +class Solution { + public: + bool isValidBST(TreeNode* root) { + if (!root) { + return true; + } + stack in_order_operating_nodes; + in_order_operating_nodes.push(root); + TreeNode* checking_node; + int64_t under_limit = numeric_limits::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; + } + }; + \ No newline at end of file diff --git a/98/step3.cpp b/98/step3.cpp new file mode 100644 index 0000000..6052262 --- /dev/null +++ b/98/step3.cpp @@ -0,0 +1,18 @@ +class Solution { + public: + bool isValidBST(TreeNode* root) { + return is_valid_bst_recursive(root, numeric_limits::min(), numeric_limits::max()); + } + + 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); + } +};