-
Notifications
You must be signed in to change notification settings - Fork 0
Create 20. Valid Parentheses.md #19
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,154 @@ | ||
| # [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/) | ||
|
|
||
| ## Step1 | ||
|
|
||
| ### 問題意図の考察 | ||
| - Parentheses: such as (), [], {}, ([{}]) each parentheses should be closed by the same type of brackets. | ||
| - Every close bracket has a corresponding open bracket of the same type. LIFO (Last In, First Out), stack... | ||
|
|
||
| ### 解法を考える | ||
| - stack (LIFO), and initialize an empty stack to keep track of opening brackets. | ||
| - Iterate through each character c in the string. | ||
| - (, [, { should be pushed into stack. | ||
| - if ), ], } came out, confirming the top of stack and corresponding. | ||
|
|
||
| ### reference | ||
| - https://github.com/ryosuketc/leetcode_grind75/pull/2/commits/988f414dda681d6ee39cf76644fd7a3556a8a9d7#diff-826d80965446351c08bff958e457c5adffdf1803b61ea51422cc264a9e6288d4 | ||
| -> step1 - step3 参考 | ||
|
|
||
|
|
||
| ```cpp | ||
| class Solution { | ||
| public: | ||
| bool isValid(string& s) { | ||
| unordered_map<char, char> open_to_close = { | ||
| {'(', ')'}, | ||
| {'{', '}'}, | ||
| {'[', ']'} | ||
| }; | ||
|
|
||
| stack<char> unmatched_open_brackets; | ||
| for (char c : s) { | ||
| if (open_to_close.contains(c)) { | ||
| unmatched_open_brackets.push(c); | ||
| continue; | ||
| } | ||
| if (unmatched_open_brackets.empty()) { | ||
| return false; | ||
| } | ||
| char expected_close = open_to_close[unmatched_open_brackets.top()]; | ||
| if (c != expected_close) { | ||
| return false; | ||
| } | ||
| unmatched_open_brackets.pop(); | ||
| } | ||
| return unmatched_open_brackets.empty(); | ||
| } | ||
| }; | ||
|
|
||
| ``` | ||
|
|
||
| ## Step2 | ||
| - https://en.cppreference.com/w/cpp/language/reference.html | ||
| -> 参照渡し. | ||
|
|
||
| - キーと値のペアを保持するハッシュマップ: https://en.cppreference.com/w/cpp/container/unordered_map.html | ||
| -> キー:ここでは開き括弧 値:対応する閉じ括弧. | ||
|
|
||
| - https://google.github.io/styleguide/cppguide.html#Variable_Names | ||
| -> 変数名の確認。table_name: snake_case. lowerCamel. | ||
|
|
||
| - for (c : s) の文法に関して: https://en.cppreference.com/w/cpp/language/range-for.html | ||
| -> char c は文字列の s の各文字を1つずつ取り出して代入する。 | ||
|
|
||
| - operator[]: unordered_map のキーに対応する値の取得に関して | ||
| -> https://en.cppreference.com/w/cpp/container/unordered_map/operator_at | ||
|
|
||
| 別解をstep2にて。Chat-GPTに壁打ちして出したものなので、解法の1つとしてmemo. | ||
| - [期待するとじ括弧]を積むスタック(別解1) | ||
| ->開き括弧を確認後、対応する閉じ括弧そのものをスタックに積む。閉じ括弧が来たらスタックの先頭と一致するかだけを見るので、マップも比較分岐も最小限で済ませる。 | ||
|
|
||
| - [配列テーブル(closing→opening)+文字列をスタックとして使う] (別解2) | ||
| ->unordered_map の代わりに 固定長配列(ASCII 128) を使って 閉じ括弧→対応する開き括弧 を O(1) 参照。スタックは std::string を使うと軽量(push/pop_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.
この発想はありませんでした。ただ 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. ほぼ変わらない気がします。> 軽量 |
||
|
|
||
|
|
||
| ```cpp | ||
| #include <string> | ||
| #include <stack> | ||
|
|
||
| //別解1 | ||
| class Solution { | ||
| public: | ||
| bool isValid(const std::string& s) { | ||
| std::stack<char> st; | ||
|
|
||
| for (char c : s) { | ||
| switch (c) { | ||
|
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. 好みの範囲かもしれませんが、括弧の種類が増えたときの拡張性なども考えると括弧はmap等で管理し、ifで分岐処理を記述したほうが簡潔なように思います。
Owner
Author
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. @maeken4 |
||
| case '(': | ||
| st.push(')'); | ||
| break; | ||
| case '{': | ||
| st.push('}'); | ||
| break; | ||
| case '[': | ||
| st.push(']'); | ||
| break; | ||
| case ')': | ||
| case '}': | ||
| case ']': | ||
| if (st.empty() || st.top() != c) { | ||
| return false; | ||
| } | ||
| st.pop(); | ||
| break; | ||
| default: | ||
| return false; | ||
| } | ||
| } | ||
| return st.empty(); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
| ``` | ||
|
|
||
| ```cpp | ||
| #include <string> | ||
| #include <array> | ||
|
|
||
| //別解2 | ||
| class Solution { | ||
| class Solution { | ||
| public: | ||
| bool isValid(const std::string& s) { | ||
| if (s.size() % 2 != 0) { | ||
| return false; | ||
| } | ||
|
|
||
| std::array<char, 128> close_to_open{}; | ||
|
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. {} を付けると 0 で初期化されるのだと思いますが、以下で必要な要素に代入しているため、 {} を外して初期化なしにしてもよいと思いました。
Owner
Author
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. @nodchip ここでは、'(', '{', '['の3つだけなので、後々代入するのであれば、初期化なしにした方がいいかもしれないですね。 順に書いていった時に、必要・不必要なこと当たり前に書けるようにします。 |
||
| close_to_open[')'] = '('; | ||
| close_to_open['}'] = '{'; | ||
| close_to_open[']'] = '['; | ||
|
Comment on lines
+128
to
+131
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. map ではなく array にしたのは意図的でしょうか。小さいものなら単純な array の方が効率がよい、というのはあるかもしれませんね。
Owner
Author
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. @ryosuketc こちらを書いた時は、「弧の種類(3種)が少なく、拡張を考えなくていいから、速さとシンプルさを優先して array を選んだ」形ですね。 |
||
|
|
||
| std::string st; | ||
| st.reserve(s.size()); | ||
|
|
||
| for (char c : s) { | ||
| if (c == '(' || c == '{' || c == '[') { | ||
| st.push_back(c); | ||
| } else { | ||
| if (st.empty() || st.back() != close_to_open[c]) { | ||
| return false; | ||
| } | ||
| st.pop_back(); | ||
| } | ||
| } | ||
| return st.empty(); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
| ``` | ||
|
|
||
| ## Step3 | ||
| 30min | ||
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.
インデントがずれているようです。