Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Valid Parentheses/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# step1

どこかで同じ問題をやっていた?
記憶があって stack に積まれた最後の閉じ括弧を対応するペアと比較する方法がすっと出てきた。

# step2

せっかくなのでナイーブな方法を考えてみた。
全部 replace すればいいかという安易な考えでコーディングしてみた。
~~Brute Force で解いてみても計算量は O(N) なので悪くはないかなとは思った。~~(正規表現でマッチングしているのでもちろん計算量がアルゴリズムの選択肢になるとは思っていないです。)

追記: 時間計算量は、最悪で O(N) の処理が O(N/2) 回ループするので、 O(N^2)になりそうと指摘いただきました。

## step3

同じようにコーディングをした。step1から変わっていない。改善を考えるのが苦手かもしれない。
17 changes: 17 additions & 0 deletions Valid Parentheses/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Solution:
def isValid(self, s: str) -> bool:
stack = []
bracket_pairs = { ")": "(", "]": "[", "}": "{"}

for char in s:
if char in bracket_pairs:
if len(stack) > 0 and stack[-1] == bracket_pairs[char]:
stack.pop()
else:
return False
else:
stack.append(char)

return len(stack) == 0


9 changes: 9 additions & 0 deletions Valid Parentheses/step2-brute-force.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Solution:
def isValid(self, s: str) -> bool:
while "()" in s or "{}" in s or "[]" in s:
s = s.replace("()", "")
s = s.replace("{}", "")
s = s.replace("[]", "")

return s == ""

15 changes: 15 additions & 0 deletions Valid Parentheses/step2-using-stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class Solution:
def isValid(self, s: str) -> bool:
stack = []
bracket_pairs = { ")": "(", "]": "[", "}": "{"}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここの変数名、close_to_openとかにすると対応関係がわかりやすくなるかなと感じました。
辞書やタプルの場合は、x_to_y のような名前の付け方があるらしいです。
https://github.com/irohafternoon/LeetCode/pull/11/files#r2024946024


for char in s:
if char in bracket_pairs:
if len(stack) > 0 and stack[-1] == bracket_pairs[char]:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if stack and stack[-1] == bracket_pairs[char]:

と書いたほうがシンプルだと思います。

stack.pop()
else:
return False
else:
stack.append(char)

return len(stack) == 0
8 changes: 8 additions & 0 deletions Valid Parentheses/step3-brute-force.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class Solution:
def isValid(self, s: str) -> bool:
while "()" in s or "{}" in s or "[]" in s:
s = s.replace("()", "")
s = s.replace("{}", "")
s = s.replace("[]", "")

return s == ""
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return not s

と、 Implicit false を使った書き方はいかがでしょうか?

参考までにスタイルガイドへのリンクを貼ります。

https://google.github.io/styleguide/pyguide.html#2144-decision

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.

上記のスタイルガイドは唯一絶対のルールではなく、複数あるスタイルガイドの一つに過ぎないということを念頭に置くことをお勧めします。また、所属するチームにより何が良いとされているかは変わります。自分の中で良い書き方の基準を持ちつつ、チームの平均的な書き方で書くことをお勧めいたします。

16 changes: 16 additions & 0 deletions Valid Parentheses/step3-using-stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution:
def isValid(self, s: str) -> bool:
stack = []
bracket_pairs = { "}": "{", "]": "[", ")": "("}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

この書き方はぱっと見で対応が取れているか分かりづらいので、開き括弧→閉じ括弧にしてスタックからポップした開き括弧をこの対応に入れて一致を見るという方法もあります

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。たしかに対応見にくいですね、!
こちらのコミットで仰るやり方も試してみました。addc28c


for char in s:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

charはC/C++の予約語なので気にする人もいるかもしれません
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.34fedgfeaxcw

if char in bracket_pairs:
if len(stack) > 0 and stack[-1] == bracket_pairs[char]:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

popしたものを見ると条件分岐が減らせるかなと思いました

stack.pop()
else:
return False
else:
stack.append(char)

return stack == []
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

こちらは空のリストはfalseであることを利用して以下のようにも書けますね

Suggested change
return stack == []
return not stack

ご参考までにGoogleのスタイルガイドではこの書き方が推奨されているようです

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://google.github.io/styleguide/pyguide.html#2144-decision


7 changes: 7 additions & 0 deletions Valid Parentheses/step4-using-bruteforce.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Solution:
def isValid(self, s: str) -> bool:
while "()" in s or "{}" in s or "[]" in s:
s = s.replace("()", "")
s = s.replace("{}", "")
s = s.replace("[]", "")
return not s
12 changes: 12 additions & 0 deletions Valid Parentheses/step4-using-stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Solution:
def isValid(self, s: str) -> bool:
stack = []
opening_to_closing = { "(": ")", "{": "}", "[": "]"}
for bracket in s:
if bracket in opening_to_closing:
stack.append(opening_to_closing[bracket])
continue
else:
if not stack or bracket != stack.pop():
return False
return not stack