From 1d3bb0bef89060b9e77d8d011bdd831b43540446 Mon Sep 17 00:00:00 2001 From: wanwan87 Date: Sun, 10 May 2026 12:14:27 +0900 Subject: [PATCH 1/4] Create 20. Valid Parentheses.md --- 20. Valid Parentheses.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 20. Valid Parentheses.md diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md new file mode 100644 index 0000000..28aa5f2 --- /dev/null +++ b/20. Valid Parentheses.md @@ -0,0 +1,39 @@ +# step1 +- 紙面上で入力パターンを考えてみた + - 入力を取り出していって (,{,[ が来ていないのに ),},] が先に来るパターンはfalseになる + - ( が来たら丸かっこフラグをたてる、{ がきたら波かっこフラグを立てる。フラグが立っていないのに 閉じる側のかっこがきたらfalse + - ループでi番目とi+1番目の入力を比較して、開きかっこがきたら閉じるかっこが来るまでi+2,i+3と進めていく + - 例えば入力が([])だったら、i番目:( i+1番目:[ でfalseなので ( を保持しして 一致する閉じかっこが来るまでループを回す + - などを考えていたが、入力が(([]))のときなどの判断が難しかったので、一旦別の方法に切り替える + - (([]))のときに 最初の(を0番目としたら、入力の一番最後である5番目に)が来ればよい。1番目の ( に対応する ) はstrの長さ-1番目に、[ に対応する ] は strの長さ-2番目に来る。鏡のように対称の位置にあるかっこを探す形であれば実現できそう + +ここまでで1時間ぐらいかかっている。 + +```python +class Solution: + def isValid(self, s: str) -> bool: + for i in range(len(s)): + if len(s) == 1: + return False + if s[i] =='(': + if s[len(s)-i-1] ==')' or s[i+1] ==')': + return True + elif s[i] =='{': + if s[len(s)-i-1] =='}' or s[i+1] =='}': + return True + elif s[i] =='[': + if s[len(s)-i-1] ==']' or s[i+1] ==']': + return True + else: + return False + return True +``` + +- sの長さ奇数のときは即falseにしてよさそう +- 今のコードだと "()(]" とかで破綻しそう。()の段階で s[i+1] ==')' で trueにしてしまっているから。 + - 即trueにしない場合、"()"のときの")"に対応するかっこを探しに行って破綻しそう + - 破綻しないようにsの長さ分forを回さず、len(s)/2も考えたが、結局"()(]"でダメそう + - 破綻しないようにパッチを当てていく方法だと、新しく追加した条件によって、もともと解決できていた個所も気付かないうちにカバーできなくなってしまっていたりする + - 対称の位置のかっこを探す方法を思いついた時に"(([]))"のような対称性のある入力のみを考えてしまったが、対称性のない入力も考えるべきだった。 + +時間をかけすぎてしまったので答えを見る。 From 1886e21c53efbc9ec4de5a557b7e6d806bf71cb5 Mon Sep 17 00:00:00 2001 From: wanwan87 Date: Sun, 10 May 2026 23:43:37 +0900 Subject: [PATCH 2/4] Update 20. Valid Parentheses.md --- 20. Valid Parentheses.md | 60 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md index 28aa5f2..9782152 100644 --- a/20. Valid Parentheses.md +++ b/20. Valid Parentheses.md @@ -9,6 +9,8 @@ ここまでで1時間ぐらいかかっている。 +以下間違い + ```python class Solution: def isValid(self, s: str) -> bool: @@ -36,4 +38,60 @@ class Solution: - 破綻しないようにパッチを当てていく方法だと、新しく追加した条件によって、もともと解決できていた個所も気付かないうちにカバーできなくなってしまっていたりする - 対称の位置のかっこを探す方法を思いついた時に"(([]))"のような対称性のある入力のみを考えてしまったが、対称性のない入力も考えるべきだった。 -時間をかけすぎてしまったので答えを見る。 +時間をかけすぎてしまったので答えを見て整理。 + +```python3 +class Solution: + def isValid(self, s: str) -> bool: + i=0 + # stackに格納していく + a=[] + for i in range(len(s)): + # ({[の場合、スタックにプッシュする + if s[i]=='('or s[i]=='['or s[i]=='{': + a.append(s[i]) + # )}]の場合 + else: + # stackが空の場合はfalse + if not a: + return False + # stackに({[が入っている場合はtopと比較する + top=a.pop() + # 入力のかっことtopが一致しない場合はfalse。 + if s[i]==')'and top!='(': + return False + if s[i]==']'and top!='[': + return False + if s[i]=='}'and top!='{': + return False + # stackが空になったらtrueを返す + return len(a)==0 +``` + + +# step2 + +- 変数名aは変えたい。stackとか? +- https://github.com/hiro111208/leetcode/pull/6/changes + - ({[はdict型に格納すると簡潔に書けそう + - 命名は (キー)_to_(値) が良いらしい + - 今回の場合だと,open_to_closeという変数に{"(":")"}のように入れていく。 + - return not stackがスタイルガイド的にはいい。あくまでガイドなのでチームでのルールに則る。 +- https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0 + - 番兵を置いておくことで条件式を1つ減らせるらしい + - stackが空の場合の条件に入らなくなるので削減できる(if not aの条件) + - “(aiu)[eo]” が入力としてきたときに、プログラムの挙動として好ましいのは何だと考えますか? + - 余計な入力は無視してtrueにする? + - これはちょっと怖いかも。関数の使用者かユーザーになにかしらのFBを返したい。 + - 入力がおかしいのでfalseにする? + - なんでfalseになっているか気づかれないかも。 + - エラーとして例外を投げる? + - 要件によるかもしれないが、かっこ以外入れないでくださいと返すとか。 + - プッシュダウンオートマトン + - 聞いたことはなかったが、オートマトン+スタックを組み合わせた計算モデル + - https://www.krrk0.com/pushdown-automaton/ + - チョムスキー階層 + - 形式言語を生成する形式文法の包含階層(形式言語の階層)で、句構造文法(phrase structure grammar)の階層」などともいう + - 形式言語:プログラミング言語を含む一部の人工言語や、機械可読なドキュメント類など、用法の変化に関して自然言語に対して厳格である言語。自然言語は話者集団によってあいまいさが残されたり、用法がうつろいゆく。 + - チョムスキー階層のタイプ2がプッシュダウンオートマトンらしい。 + - https://ja.wikipedia.org/wiki/%E3%83%81%E3%83%A7%E3%83%A0%E3%82%B9%E3%82%AD%E3%83%BC%E9%9A%8E%E5%B1%A4 From eb8ce21c4158d0d7acb06a12962beca09b3d33b0 Mon Sep 17 00:00:00 2001 From: wanwan87 Date: Mon, 11 May 2026 22:35:52 +0900 Subject: [PATCH 3/4] Update 20. Valid Parentheses.md --- 20. Valid Parentheses.md | 51 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md index 9782152..fab7379 100644 --- a/20. Valid Parentheses.md +++ b/20. Valid Parentheses.md @@ -95,3 +95,54 @@ class Solution: - 形式言語:プログラミング言語を含む一部の人工言語や、機械可読なドキュメント類など、用法の変化に関して自然言語に対して厳格である言語。自然言語は話者集団によってあいまいさが残されたり、用法がうつろいゆく。 - チョムスキー階層のタイプ2がプッシュダウンオートマトンらしい。 - https://ja.wikipedia.org/wiki/%E3%83%81%E3%83%A7%E3%83%A0%E3%82%B9%E3%82%AD%E3%83%BC%E9%9A%8E%E5%B1%A4 + + +if char != open_to_close[last_open_brackets]にする場合は、stackから#をpopしてきた時に辞書にないのでエラーとなってしまうので、辞書に登録するか、getでキーが存在しない場合に第二引数である空文字を返すようにする。 + +```python +class Solution: + def isValid(self, s: str) -> bool: + open_to_close = {"(" : ")", "{" : "}", "[" : "]"} + stack = ["#"] + for char in s: + if char in open_to_close: + stack.append(char) + continue + last_open_brackets = stack.pop() + if char != open_to_close.get(last_open_brackets,""): + return False + return stack == ["#"] +``` + + +# step3 + +```python +class Solution: + def isValid(self, s: str) -> bool: + open_to_close = {"(":")","{":"}","[":"]"} + stack = ["#"] + for char in s: + if char in open_to_close: + stack.append(char) + continue + last_opne_bracket = stack.pop() + if char != open_to_close.get(last_opne_bracket,""): + return False + return stack == ["#"] +``` + +```python +class Solution: + def isValid(self, s: str) -> bool: + open_to_close = {"(":")","{":"}","[":"]"} + stack = ["#"] + for char in s: + if char in open_to_close: + stack.append(char) + continue + last_open_bracket = stack.pop() + if char != open_to_close.get(last_open_bracket,""): + return False + return stack == ["#"] +``` From dac488d3d7bda4527f0048b0737a47ac643c7475 Mon Sep 17 00:00:00 2001 From: wanwan87 Date: Mon, 11 May 2026 22:45:17 +0900 Subject: [PATCH 4/4] Update 20. Valid Parentheses.md --- 20. Valid Parentheses.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md index fab7379..01866d6 100644 --- a/20. Valid Parentheses.md +++ b/20. Valid Parentheses.md @@ -80,13 +80,14 @@ class Solution: - https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0 - 番兵を置いておくことで条件式を1つ減らせるらしい - stackが空の場合の条件に入らなくなるので削減できる(if not aの条件) - - “(aiu)[eo]” が入力としてきたときに、プログラムの挙動として好ましいのは何だと考えますか? - - 余計な入力は無視してtrueにする? - - これはちょっと怖いかも。関数の使用者かユーザーになにかしらのFBを返したい。 - - 入力がおかしいのでfalseにする? - - なんでfalseになっているか気づかれないかも。 - - エラーとして例外を投げる? - - 要件によるかもしれないが、かっこ以外入れないでくださいと返すとか。 + - >“(aiu)[eo]” が入力としてきたときに、プログラムの挙動として好ましいのは何だと考えますか? + - 余計な入力は無視してtrueにする? + - これはちょっと怖いかも。関数の使用者かユーザーになにかしらのFBを返したい。 + - 入力がおかしいのでfalseにする? + - なんでfalseになっているか気づかれないかも。 + - エラーとして例外を投げる? + - 要件によるかもしれないが、かっこ以外の文字は入れないでくださいと返すとか。 + - 今回のコードの場合はforの中で確認すればよさそう。if char in open_to_closeのcontinueの時点で、開きかっこではないことが確定しているので、その下に閉じかっこでないことを確認(if char not in set(open_to_close.value())して、エラーを出す。 - プッシュダウンオートマトン - 聞いたことはなかったが、オートマトン+スタックを組み合わせた計算モデル - https://www.krrk0.com/pushdown-automaton/