-
Notifications
You must be signed in to change notification settings - Fork 0
20. Valid Parentheses #11
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,101 @@ | ||
| # 20. Valid Parentheses | ||
| 問題リンク: https://leetcode.com/problems/valid-parentheses/ | ||
| 言語: Python | ||
|
|
||
| # Step1 | ||
| * 訪れた文字をスタックに積む | ||
| * 訪れた文字が閉カッコの場合かつ、ひとつ前の文字が対応する開カッコの場合、スタックから2回popする | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| if len(s) <= 1: | ||
| return False | ||
|
|
||
| visited_chars = deque() | ||
|
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. deque である必要はないというのはその通りでして、追加すると |
||
|
|
||
| for c in s: | ||
| visited_chars.append(c) | ||
| if len(visited_chars) != 1: | ||
| if c == ")" and visited_chars[-2] == "(": | ||
| visited_chars.pop() | ||
| visited_chars.pop() | ||
| if c == "]" and visited_chars[-2] == "[": | ||
| visited_chars.pop() | ||
| visited_chars.pop() | ||
| if c == "}" and visited_chars[-2] == "{": | ||
| visited_chars.pop() | ||
| visited_chars.pop() | ||
|
|
||
| if len(visited_chars) == 0: | ||
| return True | ||
| else: | ||
| return False | ||
| ``` | ||
| * 解答時間: 1:03:46 | ||
| - 途中でスタックを使った方法に気づいてからは15分くらい | ||
| - 後ろから2番目を参照する方法は `visited_chars` のサイズを事前に検証しないといけないのであまり綺麗ではないと思った | ||
|
|
||
| # Step2 | ||
| ## 他人のコードを読む | ||
| * https://github.com/maeken4/Arai60/pull/6 | ||
| - C++ | ||
| - スタックを使ったアルゴリズム | ||
| - 事前にカッコの対応関係(キー:開カッコ、値:閉カッコ)を辞書で持っておく | ||
| - 今後のカッコの種類の変更に対応しやすくなる意味でも良いと思った | ||
| - 自分の場合は両方のカッコを同時にスタックに積んでいたが、これは開カッコに対応する**閉カッコ**のみをスタックに積む方法 | ||
| - 文脈自由文法(プッシュダウンオートマトン)で文法を定義できる | ||
| - `S → (S) | SS | ε` | ||
| - コンパイラの字句解析そのものか… | ||
|
|
||
| * https://github.com/ryosuketc/leetcode_arai60/pull/6 | ||
| - Python | ||
| - カッコの対応関係(キー:閉カッコ、値:開カッコ)を辞書で持っておく | ||
| - アルゴリズムは同じ | ||
| - 変数名がわかりやすい | ||
|
|
||
| ## 読みやすく直したコード | ||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| closing_to_opening_brackets = {")": "(", "]": "[", "}": "{"} | ||
|
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. opening_to_closing_brackets = {"(": ")", "[": "]", "{": "}"}と、開きカッコを先に持ってきたほうが読みやすいと思います。ロジックが少し変わりますが、過去のコードレビューを参照すれば見つかると思います。 |
||
| unmatched_open_brackets = deque() | ||
|
|
||
| for bracket in s: | ||
| if bracket in closing_to_opening_brackets: | ||
| if not unmatched_open_brackets: | ||
| return False | ||
| actual_bracket = unmatched_open_brackets.pop() | ||
| expected_bracket = closing_to_opening_brackets[bracket] | ||
| if actual_bracket != expected_bracket: | ||
| return False | ||
| else: | ||
| unmatched_open_brackets.append(bracket) | ||
|
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. (好みの問題かもしれませんが)、ひだりカッコの処理が先にあったくれた方が個人的には頭に入りやすいかもと思いました。(左かっこの方がシンプルなので、シンプルなものが先に片付いてくれて方が、最後に残っているより少し楽に感じるため) |
||
|
|
||
| return not unmatched_open_brackets | ||
| ``` | ||
|
|
||
| # Step3 | ||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| closing_to_opening_bracket = {")": "(", "]": "[", "}": "{"} | ||
| unmatched_brackets = deque() | ||
|
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. 全体的に読みやすいと思います!個人的にはstep2のようにunmatched_open_bracketsと明示してくれた方が読むのが楽に思いました。 |
||
|
|
||
| for bracket in s: | ||
|
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. 問題の制約で起きえないですが、文字列にかっこ以外の文字が含まれる可能性を考えると、bracketとして良いのだろうか、という気持ちになりました。 |
||
| if bracket in closing_to_opening_bracket: | ||
|
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. 93行目の処理を先に書いたほうが読みやすいと思いました。 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. +1 です |
||
| if not unmatched_brackets: | ||
| return False | ||
| actual_bracket = unmatched_brackets.pop() | ||
| expected_bracket = closing_to_opening_bracket[bracket] | ||
| if actual_bracket != expected_bracket: | ||
| return False | ||
| else: | ||
| unmatched_brackets.append(bracket) | ||
|
|
||
| return not unmatched_brackets | ||
| ``` | ||
| * 解答時間 | ||
| - 1回目: 3:44 | ||
| - 2回目: 4:27 | ||
| - 3回目: 3:51 | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
(step2,3含め)dequeではなくlistでも良いのかなと思いました。(popとappendしかしてなさそうなため。)
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.
コードの動きの上では変わらないと思いますが、適切なコンテナを使ったほうが意図が伝わりやすいか思います。