-
Notifications
You must be signed in to change notification settings - Fork 0
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
Create ValidParenthesis.md #7
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,112 @@ | ||
# 20.valid parentheses | ||
|
||
## すでに解いた方々(in:レビュー依頼 titleで検索) | ||
- https://github.com/tarinaihitori/leetcode/pull/7/files | ||
- https://github.com/katataku/leetcode/pull/6/files | ||
- https://github.com/frinfo702/software-engineering-association/pull/9/files | ||
- https://github.com/t0hsumi/leetcode/pull/6/files | ||
- https://github.com/SuperHotDogCat/coding-interview/pull/41/files | ||
|
||
## Step 1 | ||
### 考えたこと | ||
- Pythonの文字列の操作とstackの使い方が怪しかったので早々に諦めてこれを確認。まずは素朴に場合分けしてみた。 | ||
- len(stack)は思いつかずにAraiさんの動画を確認 | ||
|
||
* 前回「一連の練習を終えるのに1問6時間かかってしまう」と悩んでおりましたが、標準出力を使えることを前回教えてもらったおかげで今回はStep1に20分、トータルでも2時間半くらいで済みました。つまらないことでお騒がせしてすいません…。 | ||
|
||
```Python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
stack = [] | ||
|
||
for char in s: | ||
if char == "(" or char == "{" or char == "[": | ||
stack.append(char) | ||
elif stack and char == ")" and stack[-1] == "(": | ||
stack.pop() | ||
elif stack and char == "}" and stack[-1] == "{": | ||
stack.pop() | ||
elif stack and char == "]" and stack[-1] == "[": | ||
stack.pop() | ||
else: | ||
print(stack) | ||
return False | ||
|
||
return len(stack) == 0 | ||
``` | ||
|
||
## Step 2 | ||
### 学んだこと | ||
- 場合分けが多いので、continueや早期returnを用いていかに読みやすくするかが結構論じられている:https://github.com/tarinaihitori/leetcode/pull/7/files | ||
- 辞書を使うやり方が場合分けが減らせてスマート | ||
- Return len(stack)するよりimplicit falseを使う方流儀もあるが、趣味の範囲っぽいので周囲に合わせれば良いとのこと | ||
- charが([{と一致するかはc in “([{”でも通るのは知らなかった: https://github.com/katataku/leetcode/pull/6/files#r1847770818 | ||
- 番兵を入れておくやり方、気になる:https://github.com/tarinaihitori/leetcode/pull/7/files#r1817714323 | ||
- 今回はListでpopとappendしたが、dequeを使えばstackの左側からも取り出したり追加したりできる: https://note.nkmk.me/python-collections-deque/ | ||
- チョムスキー階層、プッシュダウンオートマトンはよく分からないのでとりあえずスルー。こちらの方が関係ある箇所をまとめてくれていた:https://github.com/BumbuShoji/Leetcode/pull/7/files (後で読む:https://str.i.kyushu-u.ac.jp/~takeda/Lectures/FormalLanguageTheory2019/Resume/FormalLanguageTheory2019-11.pdf) | ||
- 何が問題になっているのか理解が怪しいけれど、「双方向リストの機能を使っていないのにdequeを使うと無駄な処理が増えるので、O(1)同士でも違いがあることに敏感になろう」という話と理解した: https://github.com/BumbuShoji/Leetcode/pull/7/files#r1810557932 | ||
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. よくわかりました、ありがとうございます。 |
||
- 一度辞書を使って書いてみよう | ||
|
||
```Python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
bracket_pair = {"(": ")", "{": "}", "[": "]"} | ||
stack = [] | ||
|
||
for char in s: | ||
if char in bracket_pair: | ||
stack.append(char) | ||
continue | ||
if not stack: | ||
return False | ||
if char != bracket_pair[stack[-1]]: | ||
return False | ||
stack.pop() | ||
|
||
return len(stack) == 0 | ||
|
||
``` | ||
|
||
## Step 3 | ||
### コメント | ||
- Step2で書いたIf文にcontinueを重ねるのが読みやすいが、頭からこれが書いていける感じがしない。。。一度別のコードを書いてから上の形に書き直す感じになりそうなので、自分にとって頭から自然に書ける書き方でしばらく書いてみたが、結果これまでと違ってStep3の書き方がなかなか1通りに収束しない。Step2の様なコードを頭から書きくだせる様な練習をすべきなのか…? -> 「if continueになれていない」というのが原因に思えるので、「常識」的な感覚に合わせるためにもstep2が自然に感じる様に練習する方がいい気がする。 | ||
- 5:15, 5:30, 4:10 | ||
|
||
```Python | ||
def isValid(self, s: str) -> bool: | ||
bracket_pairs = {"(": ")", "[": "]", "{": "}"} | ||
stack = [] | ||
|
||
for char in s: | ||
if char in bracket_pairs: | ||
stack.append(char) | ||
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. continue を書く気持ちは、ここの行まで来たところで、「合流しない」と思っているかです。 if char in bracket_pairs:
stack.append(char)
elif B:
C
else:
D
E の E が存在しないと思っているならば、そうであることを頭の中に残しておかず、continue と書いてうっかり E を別の事情で書きたくなったときに間違えないようにしようという気持ちです。 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. しっくり来ました、ありがとうございます。 |
||
elif char in bracket_pairs.values(): | ||
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. sが入力条件を必ず満たすとする場合、ここはelseでいい様に思います(一個前のifでcharが「開きかっこ」かチェックしているため、ここでは必ず「閉じかっこ」=bracket_pairs.values()のどれかになります)。 |
||
if stack and char == bracket_pairs[stack[-1]]: | ||
stack.pop() | ||
else: | ||
return False | ||
|
||
return len(stack) == 0 | ||
``` | ||
|
||
## 悩んだけれど最終的にこっちで書いた | ||
```Python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
bracket_pairs = {"(": ")", "[": "]", "{": "}"} | ||
stack = [] | ||
|
||
for char in s: | ||
if char in bracket_pairs: | ||
stack.append(char) | ||
continue | ||
if not stack: | ||
return False | ||
if char != bracket_pairs[stack[-1]]: | ||
return False | ||
stack.pop() | ||
|
||
return len(stack) == 0 | ||
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. PEP8, google style guideからは、 For sequences, (strings, lists, tuples), use the fact that empty sequences are false: 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. len(stack)については好みレベルとのコメントを見かけたのでこちらを採用しましたが、一貫性と言われるとおっしゃる通りだなと思います。ありがとうございます。 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 comment
The reason will be displayed to describe this comment to others. Learn more.
stack = ["*"]
bracket_pair = {"(": ")", "{": "}", "[": "]", "*": ""}
とでもしておくと not stack にならなくなります。
最後、"*" ひとつだけが残っているかで判別です。
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.
なるほど、こんなふうに書けるんですね。番兵について、先のLinkedListの問題で見ただけだったので、こんなことが出来ることすら想像できてませんでした。
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.
私の意図は "*" でしたが、"" でも構いません。(斜体開始と解釈されて消えてしまいました。)