diff --git a/01-15/11.Valid-Parentheses/1.cpp b/01-15/11.Valid-Parentheses/1.cpp new file mode 100644 index 0000000..4843d0c --- /dev/null +++ b/01-15/11.Valid-Parentheses/1.cpp @@ -0,0 +1,66 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// 10分 +// <感想> +// これ正直10分じゃ無理だろ、と思っていたが意外と書けて嬉しい。 +// 最初の方でどうするのがいいか少し時間を取って考えた。 +// 最初に思い付いたのがpre変数を用意して、 +// ひとつ前の文字に対応する括弧のみ受けつけ続けるみたいな(結局うまく行かなそう)。 +// そっから何かの拍子にstackを使うことを思いつき、 +// 途中でclosing_to_openingが必要になり +// switchで書いていたロジックをclosing_to_openingを使った +// ifに書き換えるという流れ +// <疑問・不安点(・個人的な感想、違う意見があれば教えてほしいもの)> +// - L49を空けるか否か +// - closing_to_openingとopening_bracketsのどちらを先に宣言するか +// (細かいけど...) +// <他の人のを見てコメント> +// - なるほど。そういえばValid ParenthesesもCSZAPで触れていたかもしれない。 +// https://discord.com/channels/1084280443945353267/1201211204547383386/1202541275115425822 +// - そうか、closing_to_openingじゃなくてもopening_to_closingでもよかったのか… +// うーん、でもその場合2回map::findすることになるな +// - stackに番兵を入れてstack::emptyを呼び出さなくていいようにしている +// ものがあった。頭いい。 +// - closing_to_opening定数だからスネークケースじゃなかったわ。 +// +// +// +// +// +// +// +// L40(行数調整用コメント) +class Solution { + public: + bool isValid(string s) { + static const map closing_to_opening{ + {')', '('}, + {'}', '{'}, + {']', '['}, + }; + + stack opening_brackets; + for (auto c : s) { + if (auto it = closing_to_opening.find(c); + it != closing_to_opening.end()) { + auto opening = it->second; + if (!opening_brackets.empty() && opening_brackets.top() == opening) { + opening_brackets.pop(); + } else { + return false; + } + } else { + opening_brackets.push(c); + } + } + return opening_brackets.empty(); + } +}; diff --git a/01-15/11.Valid-Parentheses/2.cpp b/01-15/11.Valid-Parentheses/2.cpp new file mode 100644 index 0000000..733a22c --- /dev/null +++ b/01-15/11.Valid-Parentheses/2.cpp @@ -0,0 +1,35 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include + +using namespace std; + +// <時間> +// 5分 +// <感想> +class Solution { + public: + bool isValid(const string &brackets) { + static const map kClosingToOpening{ + {')', '('}, + {'}', '{'}, + {']', '['}, + }; + stack opening_brackets; + opening_brackets.push('*'); // sentinel + for (auto bracket : brackets) { + if (auto it = kClosingToOpening.find(bracket); + it != kClosingToOpening.end()) { + auto opening = it->second; + if (opening_brackets.top() != opening) return false; + opening_brackets.pop(); + } else { + opening_brackets.push(bracket); + } + } + return opening_brackets.size() == 1; + } +}; diff --git a/01-15/11.Valid-Parentheses/3.cpp b/01-15/11.Valid-Parentheses/3.cpp new file mode 100644 index 0000000..479f1ef --- /dev/null +++ b/01-15/11.Valid-Parentheses/3.cpp @@ -0,0 +1,49 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include +#include +#include + +using namespace std; + +// <時間> +// 15分 +// <コメント> +// - corresponding_bracketとopen_bracketは最初逆に名前を付けていた。 +// - corresponding_bracketは最初corresponding_open_bracketとしていたが、 +// openはなくても伝わると思い消した。 +// - だが、読む側に取ってどう見えるかは分からない。 +// - correspondingみたいな意味の名前は付けることが多いと思うが、 +// もっと短めの単語はないものか。 +class Solution { + public: + bool isValid(const string &brackets) { + static const map kCloseToOpen{ + {')', '('}, + {'}', '{'}, + {']', '['}, + }; + stack open_brackets; + open_brackets.push('\0'); + for (auto bracket : brackets) { + // In the case `bracket` is an open bracket. + auto close_and_open = kCloseToOpen.find(bracket); + if (close_and_open == kCloseToOpen.end()) { + open_brackets.push(bracket); + continue; + } + + // In the case `bracket` is a close bracket. + auto open_bracket = close_and_open->second; + auto corresponding_bracket = open_brackets.top(); + open_brackets.pop(); + if (corresponding_bracket != open_bracket) { + return false; + } + } + return open_brackets.size() == 1; + } +}; diff --git a/01-15/11.Valid-Parentheses/4.cpp b/01-15/11.Valid-Parentheses/4.cpp new file mode 100644 index 0000000..186d5c9 --- /dev/null +++ b/01-15/11.Valid-Parentheses/4.cpp @@ -0,0 +1,48 @@ +#if __has_include("../../debug.hpp") +#include "../../debug.hpp" +#endif +// ここまでローカルでのデバッグ用なので気にしないでください -------------------- + +#include +#include +#include + +using namespace std; + +// <時間> +// 10分 +// <感想> +// 多分3.cppよりこっちの方が読みやすい。 +// <コメント> +// - auto open_bracket = open_brackets.top(); +// で新しく変数を作ろうかとも思ったが、無駄に変数が多くても +// 読みづらいかなと思い作らないことにした。 +class Solution { + public: + bool isValid(const string &brackets) { + static const map kOpenToClose{ + {'(', ')'}, + {'{', '}'}, + {'[', ']'}, + }; + stack open_brackets; + for (auto bracket : brackets) { + // In the case `bracket` is an open bracket. + if (kOpenToClose.contains(bracket)) { + open_brackets.push(bracket); + continue; + } + + // In the case `bracket` is a close bracket. + if (open_brackets.empty()) { + return false; + } + auto close_bracket = kOpenToClose.at(open_brackets.top()); + open_brackets.pop(); + if (bracket != close_bracket) { + return false; + } + } + return open_brackets.empty(); + } +}; diff --git a/01-15/11.Valid-Parentheses/README.md b/01-15/11.Valid-Parentheses/README.md new file mode 100644 index 0000000..8ca741d --- /dev/null +++ b/01-15/11.Valid-Parentheses/README.md @@ -0,0 +1,3 @@ +# 20. Valid Parentheses + +