From 4669ab61e8796d7d903e10beb19cfbd1a1d28adc Mon Sep 17 00:00:00 2001 From: Taito Ohsumi Date: Wed, 27 Nov 2024 22:58:54 +1100 Subject: [PATCH 1/2] Add 20. Valid Parentheses.md --- 20. Valid Parentheses.md | 107 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 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..37a995f --- /dev/null +++ b/20. Valid Parentheses.md @@ -0,0 +1,107 @@ +# 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)では特に指定がなかった。 +# 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 + and open_to_close[open_bracket_stack[-1]] == bracket): + open_bracket_stack.pop() + continue + return False + return not open_bracket_stack +``` \ No newline at end of file From b4f402d585ce49ca7e5599bc278d69c4c7def4f3 Mon Sep 17 00:00:00 2001 From: Taito Ohsumi Date: Wed, 4 Dec 2024 14:27:25 +1100 Subject: [PATCH 2/2] Add step 4 --- 20. Valid Parentheses.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/20. Valid Parentheses.md b/20. Valid Parentheses.md index 37a995f..8e45ac2 100644 --- a/20. Valid Parentheses.md +++ b/20. Valid Parentheses.md @@ -104,4 +104,43 @@ class Solution: 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 ``` \ No newline at end of file