Skip to content
Merged
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
22 changes: 22 additions & 0 deletions 020-valid-parentheses/memo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## step1で考えたこと

それぞれの括弧に対応するものを取り除いていき、最後に残っていればFalse, そうでないならTrue

=> whileの終了条件をどうするか?
無限ループになってしまう
さらにStep1のコードだと本来FalseであるべきものもTrueになってしまう

カッコを分けて取り除くのではなく、セットで取り除けば良いのでは??

## step2
コードは適切に求められたことを処理できているがRuntimeが若干遅いのが気になる
Time Complexity: O(n^2).
Space Complexity: O(n).
=> Brute Force


もっと早くするにはどうすべきか
- whileを使わないで書く
=> Using stack

## step3
30 changes: 30 additions & 0 deletions 020-valid-parentheses/step1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 動かないコード

class Solution:
def isValid(self, s: str) -> bool:
while s:
if "(" in s:
s.pop("(")
s.pop(")")
elif "[" in s:
s.pop("[")
s.pop("]")
elif "{" in s:
s.pop("{")
s.pop("}")

return True

class Solution:
def isValid(self, s: str) -> bool:
while s:
if "()" in s:
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

競技プログラミング同好会の hmuta 氏が、このようなコードを書かれていたのを思い出しました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

これ、チェックせずにどんどん replace し、短くならなくなったら False という方法はできることはできます。
計算量は2乗ですが、Native コードなのでそんなに遅くない気がします。

s = s.replace("()", "")
elif "[]" in s:
Comment on lines +20 to +23
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

この解法は自分では思いついていなかったため、参考になりました!

s = s.replace("[]", "")
elif "{}" in s:
s = s.replace("{}", "")

# return not s と書くのが簡潔でわかりやすい。
if s: return True
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

if s: return False
else: return True

が正しいように思います。

また、 Implicit False を用いて、

return not s

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

else: return False
8 changes: 8 additions & 0 deletions 020-valid-parentheses/step2.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 == ""
15 changes: 15 additions & 0 deletions 020-valid-parentheses/step3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## 別解
class Solution:
def isValid(self, s: str) -> bool:
stack = []
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

個人的には変数名に、どのようなデータ構造として使うかより、中にどのような値が含まれているかを付けたほうが、読み手に取って理解の助けになると思います。 open_brackets はいかがでしょうか?

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

毎回こういった変数に名前をつけるのが苦手で良い命名が思いつかないです。。。
参考になります

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

個人的には変数名に、どのようなデータ構造として使うかより、中にどのような値が含まれているかを付けたほうが、読み手に取って理解の助けになる

私も同意です。

open_to_close = {"()": ")", "[]": "]", "{": "}"}

Comment on lines +5 to +6
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

前回のコミット(baadf67) で、open_to_closeに余計な括弧が入り込んでしまっているみたいです。

また、close_to_open から open_to_close にする場合は以下の変更を加える必要があると思います。

  • if c in open_to_close の方で stack に追加
  • else の方で検証を行う必要。

これは、valid な出力の場合 open → close の順に括弧がくるためです。具体的には、if c in open_to_closeで検証を行う方法だと、入力が ()の場合、最初に(がきますが、検証を行う際に close_brackets の中身がまだ空なため False になります。

たとえば、以下のような書き方があると思います。

class Solution:
    def isValid(self, s: str) -> bool:
        close_bracktes = []
        open_to_close = {"(": ")", "[": "]", "{": "}"}

        for c in s:
            if c in open_to_close:
                close_bracktes.append(open_to_close[c])
            else:
                if not close_bracktes:
                  return False
                expected_bracket = close_bracktes.pop()
                if c != expected_bracket:
                    return False
        return not close_bracktes

for c in s:
if c in open_to_close:
if stack and stack[-1] == open_to_close[c]:
stack.pop()
else:
return False
else:
stack.append(c)
return True if not stack else False