-
Notifications
You must be signed in to change notification settings - Fork 0
Add 20. Valid Parentheses.md #6
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,146 @@ | ||
# step 1 | ||
stackを使う有名問題みたいなイメージ。 | ||
|
||
文字列を左から順に見ていって、閉じかっこがきたら**それに対応する開きかっこ**がstack上に存在するかを | ||
調べるということの太字部分を意識して、close_to_openと書いていた。 | ||
|
||
文字列の長さをnとして | ||
- time complexity: O(n) | ||
- space complexity: O(n) (Auxiliary space: O(n)) | ||
|
||
```python3 | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
stack = [] | ||
close_to_open = {')': '(', '}': '{', ']': '['} | ||
for parenthesis in s: | ||
if parenthesis in close_to_open: | ||
if stack == [] \ | ||
or stack[-1] != close_to_open[parenthesis]: | ||
return False | ||
stack.pop() | ||
else: | ||
stack.append(parenthesis) | ||
return stack == [] | ||
``` | ||
# step 2 | ||
参考 | ||
- https://github.com/katataku/leetcode/pull/6/files | ||
- https://google.github.io/styleguide/pyguide.html#214-truefalse-evaluations | ||
> For sequences (strings, lists, tuples), use the fact that empty sequences are false, so if seq: and if not seq: are preferable to if len(seq): and if not len(seq): respectively. | ||
- https://peps.python.org/pep-0008/#other-recommendations:~:text=For%20sequences%2C%20(strings%2C%20lists%2C%20tuples)%2C%20use%20the%20fact%20that%20empty%20sequences%20are%20false%3A | ||
- PEP8, google style guideともに、sequenceに対してはlen()を用いてのブールチェックはしない。 | ||
- https://en.wikipedia.org/wiki/Bracket | ||
open, closeの他に、left, rightもあるという話 | ||
> Brackets are typically deployed in symmetric pairs, and an individual bracket may be identified as a 'left' or 'right' bracket or, alternatively, an "opening bracket" or "closing bracket" | ||
- 実装はほぼ同じだった。相違点はclose_to_openをopen_to_closeとしていた点と、 | ||
stackをopening_parenthesesにしていた点。前者については、初期化部分は`)(`こういう文字列が並んでいるより、`()`のほうが見やすい感覚があるのでより直感的だと思った。 | ||
後者に関しては、stackの中にはopen parenthesesしか入らないから、こちらの実装の方が読みやすく感じた。 | ||
- https://github.com/konnysh/arai60/pull/6 | ||
- open, close parenthesisそれぞれに対する処理を関数化する解法があった。 | ||
- こちらもopen_to_closeを使用していた。 | ||
- https://github.com/tarinaihitori/leetcode/pull/7/files | ||
- if, elseなどで処理が離れる場合は、continueやreturnしたりして、下まで見に行かなくていいようしたい。というより、離れてると読みにくいなと感じられると良さそう。 | ||
- https://docs.python.org/3/library/collections.html#deque-objects | ||
dequeをつかってstackとすることも可能 | ||
- https://github.com/python/cpython/blob/main/Modules/_collectionsmodule.c#L81-L83 | ||
> Data for deque objects is stored in a doubly-linked list of fixed length blocks. | ||
|
||
複数データが入れられる固定サイズのブロックをdoubly-linked listで繋いでいるみたい。こうすることでmalloc(), free()の回数を減らしている。(cpythonのソースは大量のマクロと長い行数から読めるわけないだろと思っていたが、doubly-linked listを使った一つのノードに一つのデータが対応するタイプのdequeは実装したことがあったので、このくらいのコードならなんとなくの気持ちくらいはわかりそうだなぁと思った。) | ||
|
||
- https://google.github.io/styleguide/pyguide.html#284-decision | ||
> Use default iterators and operators for types that support them, like lists, dictionaries, and files. The built-in types define iterator methods, too. Prefer these methods to methods that return lists, except that you should not mutate a container while iterating over it. | ||
``` | ||
Yes: for key in adict: ... | ||
if obj in alist: ... | ||
for line in afile: ... | ||
for k, v in adict.items(): ... | ||
|
||
No: for key in adict.keys(): | ||
for line in afile.readlines(): ... | ||
``` | ||
|
||
```python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
open_to_close = { | ||
'(': ')', | ||
'{': '}', | ||
'[': ']' | ||
} | ||
open_bracket_stack = [] | ||
for bracket in s: | ||
if bracket in open_to_close: | ||
open_bracket_stack.append(bracket) | ||
continue | ||
|
||
if (not open_bracket_stack \ | ||
or open_to_close[open_bracket_stack[-1]] != bracket): | ||
return False | ||
|
||
open_bracket_stack.pop() | ||
return not open_bracket_stack | ||
``` | ||
|
||
- `open_bracket_stack`という名前はopen_bracketしか入らないこと・初期化時にリストを代入しているが用法としてはstackとして使うことがわかるようにした。 | ||
- `or open_to_close[open_bracket_stack[-1]] != bracket):`はインデントして、下の部分が条件式ではないことを明確にした。[PEP8](https://peps.python.org/pep-0008/#indentation)では特に指定がなかった。 | ||
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. こういうフォーマットは、それなりに幅があって正解がないものであるということです。 |
||
# step 3 | ||
```python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
open_to_close = { | ||
'(': ')', | ||
'{': '}', | ||
'[': ']' | ||
} | ||
open_bracket_stack = [] | ||
for bracket in s: | ||
if bracket in open_to_close: | ||
open_bracket_stack.append(bracket) | ||
continue | ||
if (open_bracket_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. 自分は2つのif文に分けるかなと思いますが、好みかもしれないです。 |
||
and open_to_close[open_bracket_stack[-1]] == bracket): | ||
open_bracket_stack.pop() | ||
continue | ||
return False | ||
return not open_bracket_stack | ||
``` | ||
|
||
# step 4 | ||
- フォーマットには厳格な正解がない. formatterが何をしてるのかも参考になるという話 | ||
- https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#how-black-wraps-lines | ||
- [google style guide](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods:~:text=the%20point%20of%20having%20style%20guidelines%20is%20to%20have%20a%20common%20vocabulary%20of%20coding%20so%20people%20can%20concentrate%20on%20what%20you%E2%80%99re%20saying%20rather%20than%20on%20how%20you%E2%80%99re%20saying%20it.)もこの話に通じるなと感じた | ||
> The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you’re saying rather than on how you’re saying it. | ||
- dictではなく、open, close parenthesesのペアをそれぞれリストで所持する解法もあった | ||
- step 3では、うまく次に進める場合はcontinueというループの書き方をしていたが、if文を分けるかもという意見があった。 | ||
|
||
その他 | ||
- backslashを行繋ぎ | ||
- これをすると、backslash以降にコメントを入れた際に動かなくなるためよろしくない。 | ||
- trailing commas:縦に並び、closing parenthesisと最後の要素が同一行にないのならつけた方が無難 | ||
- [PEP 8](https://peps.python.org/pep-0008/#when-to-use-trailing-commas) | ||
- [google style guide](https://google.github.io/styleguide/pyguide.html#341-trailing-commas-in-sequences-of-items) | ||
|
||
```python | ||
class Solution: | ||
def isValid(self, s: str) -> bool: | ||
open_to_close = { | ||
'(': ')', | ||
'{': '}', | ||
'[': ']', | ||
} | ||
open_parentheses_stack = [] | ||
|
||
for parenthesis in s: | ||
if parenthesis in open_to_close: | ||
open_parentheses_stack.append(parenthesis) | ||
continue | ||
|
||
if not open_parentheses_stack: | ||
return False | ||
if open_to_close[open_parentheses_stack[-1]] != parenthesis: | ||
return False | ||
open_parentheses_stack.pop() | ||
|
||
return not open_parentheses_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.
popと条件分岐を同時にできるのでこのような書き方もありかなと思いました。