diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md new file mode 100644 index 0000000..03ea2d1 --- /dev/null +++ b/20. Valid Parentheses.md @@ -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 open_to_close = { + {'(', ')'}, + {'{', '}'}, + {'[', ']'} + }; + + stack 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)。 + + +```cpp +#include +#include + +//別解1 +class Solution { + public: + bool isValid(const std::string& s) { + std::stack st; + + for (char c : s) { + switch (c) { + 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 +#include + +//別解2 +class Solution { +class Solution { + public: + bool isValid(const std::string& s) { + if (s.size() % 2 != 0) { + return false; + } + + std::array close_to_open{}; + close_to_open[')'] = '('; + close_to_open['}'] = '{'; + close_to_open[']'] = '['; + + 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