From b47e5526226da2f9dd1a2915b72085398c2cab35 Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:28:31 +0900 Subject: [PATCH 1/3] Create 20.md --- stack/20_valid_parentheses/20.md | 113 +++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 stack/20_valid_parentheses/20.md diff --git a/stack/20_valid_parentheses/20.md b/stack/20_valid_parentheses/20.md new file mode 100644 index 0000000..c28f446 --- /dev/null +++ b/stack/20_valid_parentheses/20.md @@ -0,0 +1,113 @@ +# 1st +- 前提: Arai60は一度一周しているが、期間をあけてなるべく忘れて取り組む(linkedList の方で思い出しながらと書きましたが、なるべく初見の状態で、どれだけやれるようになったかみていきたい) +- 問題: [20. Valid Parentheses](https://leetcode.com/problems/valid-parentheses/description/) +- コメント集: [20. Valid Parentheses](https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.ns0bie22a6m) + - 引数に想定外がきた時はどうする?が気になったので実装に含めてみました + - 引数に対して、想定しない値がの場合は `IllegalArgumentException` を投げるようにしました + - が、コンパイルとか Linter のことを考えると、`(ai){ueo}` みたいなのが来たときは continue とかの方が良いのかもと思ったりしたので別解として載せました +- 所感 + - コンパイル、 Linter で高速に動いてくれないと困るよなと思いました + +### 実装 +- 時間計算量: O(N) --> 引数 s を全て走査するから +- 空間計算量: O(N) --> open の記号だけ Stack につめる、最悪全て open 記号だから +- 回答時間: 無制限(コメントをちゃんと読んでみたり、変数名の命名にこだわったりしてみました) + +```java +class Solution { + private final Map validParentheses = Map.of( + '(', ')', + '[', ']', + '{', '}' + ); + + public boolean isValid(String s) { + Stack openSymbols = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char symbol = s.charAt(i); + + if (isIllegalSymbol(symbol)) { + throw new IllegalArgumentException("Invalid Character is detected, symbol is " + symbol); + } + + if (isOpenSymbol(symbol)) { + openSymbols.push(symbol); + } else { + if (openSymbols.empty()) { + return false; + } + char peekedOpenSymbol = openSymbols.peek(); + if (isMatched(symbol, peekedOpenSymbol)) { + openSymbols.pop(); + } else { + // 合致しない時点で false + return false; + } + } + } + + return openSymbols.empty(); + } + + private boolean isIllegalSymbol(char symbol) { + return !validParentheses.containsKey(symbol) && !validParentheses.containsValue(symbol); + } + + private boolean isOpenSymbol(char symbol) { + return validParentheses.containsKey(symbol); + } + + private boolean isMatched(char symbol, char peekedOpenSymbol) { + return validParentheses.get(peekedOpenSymbol) == symbol; + } +} +``` + +- 別解 + - `isIllegalSymbol()` を削除し、引数として妥当でない場合は `continue` する方針にしました + - コンパイラとか Linter でこんな処理が動いているんだろうなで書きました +```java +class Solution { + private final Map validParentheses = Map.of( + '(', ')', + '[', ']', + '{', '}' + ); + + public boolean isValid(String s) { + Stack openSymbols = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char symbol = s.charAt(i); + + if (isOpenSymbol(symbol)) { + openSymbols.push(symbol); + } else if (isCloseSymbol(symbol)) { + if (openSymbols.empty()) { + return false; + } + char peekedOpenSymbol = openSymbols.peek(); + if (isMatched(symbol, peekedOpenSymbol)) { + openSymbols.pop(); + } else { + // 合致しない時点で false + return false; + } + } + } + + return openSymbols.empty(); + } + + private boolean isOpenSymbol(char symbol) { + return validParentheses.containsKey(symbol); + } + + private boolean isCloseSymbol(char symbol) { + return validParentheses.containsValue(symbol); + } + + private boolean isMatched(char symbol, char peekedOpenSymbol) { + return validParentheses.get(peekedOpenSymbol) == symbol; + } +} +``` From b20284adf04d9feff5a3e56f35ca4410aafb0be7 Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Sun, 12 Oct 2025 14:53:52 +0900 Subject: [PATCH 2/3] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=87=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=82=92=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stack/20_valid_parentheses/20.md | 152 +++++++++++++++---------------- 1 file changed, 75 insertions(+), 77 deletions(-) diff --git a/stack/20_valid_parentheses/20.md b/stack/20_valid_parentheses/20.md index c28f446..05f8ba6 100644 --- a/stack/20_valid_parentheses/20.md +++ b/stack/20_valid_parentheses/20.md @@ -14,52 +14,51 @@ - 回答時間: 無制限(コメントをちゃんと読んでみたり、変数名の命名にこだわったりしてみました) ```java -class Solution { - private final Map validParentheses = Map.of( - '(', ')', - '[', ']', - '{', '}' - ); - - public boolean isValid(String s) { - Stack openSymbols = new Stack<>(); - for (int i = 0; i < s.length(); i++) { - char symbol = s.charAt(i); - - if (isIllegalSymbol(symbol)) { - throw new IllegalArgumentException("Invalid Character is detected, symbol is " + symbol); - } - - if (isOpenSymbol(symbol)) { - openSymbols.push(symbol); - } else { - if (openSymbols.empty()) { - return false; +class Solution { + private final Map validParentheses = Map.of( + '(', ')', + '[', ']', + '{', '}' + ); + + public boolean isValid(String s) { + Stack openSymbols = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char symbol = s.charAt(i); + + if (isIllegalSymbol(symbol)) { + throw new IllegalArgumentException("Invalid Character is detected, symbol is " + symbol); + } + + if (isOpenSymbol(symbol)) { + openSymbols.push(symbol); + } else { + if (openSymbols.empty()) { + return false; + } + char peekedOpenSymbol = openSymbols.peek(); + if (isMatched(symbol, peekedOpenSymbol)) { + openSymbols.pop(); + } else { + // 合致しない時点で false + return false; + } + } } - char peekedOpenSymbol = openSymbols.peek(); - if (isMatched(symbol, peekedOpenSymbol)) { - openSymbols.pop(); - } else { - // 合致しない時点で false - return false; - } - } + return openSymbols.empty(); } - return openSymbols.empty(); - } - - private boolean isIllegalSymbol(char symbol) { - return !validParentheses.containsKey(symbol) && !validParentheses.containsValue(symbol); - } + private boolean isIllegalSymbol(char symbol) { + return !validParentheses.containsKey(symbol) && !validParentheses.containsValue(symbol); + } - private boolean isOpenSymbol(char symbol) { - return validParentheses.containsKey(symbol); - } + private boolean isOpenSymbol(char symbol) { + return validParentheses.containsKey(symbol); + } - private boolean isMatched(char symbol, char peekedOpenSymbol) { - return validParentheses.get(peekedOpenSymbol) == symbol; - } + private boolean isMatched(char symbol, char peekedOpenSymbol) { + return validParentheses.get(peekedOpenSymbol) == symbol; + } } ``` @@ -68,46 +67,45 @@ class Solution { - コンパイラとか Linter でこんな処理が動いているんだろうなで書きました ```java class Solution { - private final Map validParentheses = Map.of( - '(', ')', - '[', ']', - '{', '}' - ); - - public boolean isValid(String s) { - Stack openSymbols = new Stack<>(); - for (int i = 0; i < s.length(); i++) { - char symbol = s.charAt(i); - - if (isOpenSymbol(symbol)) { - openSymbols.push(symbol); - } else if (isCloseSymbol(symbol)) { - if (openSymbols.empty()) { - return false; - } - char peekedOpenSymbol = openSymbols.peek(); - if (isMatched(symbol, peekedOpenSymbol)) { - openSymbols.pop(); - } else { - // 合致しない時点で false - return false; + private final Map validParentheses = Map.of( + '(', ')', + '[', ']', + '{', '}' + ); + + public boolean isValid(String s) { + Stack openSymbols = new Stack<>(); + for (int i = 0; i < s.length(); i++) { + char symbol = s.charAt(i); + + if (isOpenSymbol(symbol)) { + openSymbols.push(symbol); + } else if (isCloseSymbol(symbol)) { + if (openSymbols.empty()) { + return false; + } + char peekedOpenSymbol = openSymbols.peek(); + if (isMatched(symbol, peekedOpenSymbol)) { + openSymbols.pop(); + } else { + // 合致しない時点で false + return false; + } + } } - } + return openSymbols.empty(); } - return openSymbols.empty(); - } - - private boolean isOpenSymbol(char symbol) { - return validParentheses.containsKey(symbol); - } + private boolean isOpenSymbol(char symbol) { + return validParentheses.containsKey(symbol); + } - private boolean isCloseSymbol(char symbol) { - return validParentheses.containsValue(symbol); - } + private boolean isCloseSymbol(char symbol) { + return validParentheses.containsValue(symbol); + } - private boolean isMatched(char symbol, char peekedOpenSymbol) { - return validParentheses.get(peekedOpenSymbol) == symbol; - } + private boolean isMatched(char symbol, char peekedOpenSymbol) { + return validParentheses.get(peekedOpenSymbol) == symbol; + } } ``` From 00a01d002d3caf5b0fdaa40780a76c8aed555d84 Mon Sep 17 00:00:00 2001 From: busker <165013324+hiroki-horiguchi-dev@users.noreply.github.com> Date: Tue, 21 Oct 2025 00:17:05 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=E6=8C=87=E6=91=98=E4=BA=8B=E9=A0=85?= =?UTF-8?q?=E3=82=92=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stack/20_valid_parentheses/20.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stack/20_valid_parentheses/20.md b/stack/20_valid_parentheses/20.md index 05f8ba6..622e925 100644 --- a/stack/20_valid_parentheses/20.md +++ b/stack/20_valid_parentheses/20.md @@ -15,14 +15,14 @@ ```java class Solution { - private final Map validParentheses = Map.of( + private static final Map validParentheses = Map.of( '(', ')', '[', ']', '{', '}' ); public boolean isValid(String s) { - Stack openSymbols = new Stack<>(); + Deque openSymbols = new ArrayDeque<>(); for (int i = 0; i < s.length(); i++) { char symbol = s.charAt(i); @@ -67,15 +67,15 @@ class Solution { - コンパイラとか Linter でこんな処理が動いているんだろうなで書きました ```java class Solution { - private final Map validParentheses = Map.of( + private static final Map validParentheses = Map.of( '(', ')', '[', ']', '{', '}' ); public boolean isValid(String s) { - Stack openSymbols = new Stack<>(); - for (int i = 0; i < s.length(); i++) { + Deque openSymbols = new ArrayDeque<>(); + for (int i = 0; i < s.length(); i++) { char symbol = s.charAt(i); if (isOpenSymbol(symbol)) {