-
Notifications
You must be signed in to change notification settings - Fork 0
20. valid parentheses #5
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,36 @@ | ||
| import timeit | ||
|
|
||
|
|
||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| open_to_close = { | ||
| '(': ')', | ||
| '{': '}', | ||
| '[': ']' | ||
| } | ||
|
|
||
| open_brackets = [None] # Put None as a sentinel | ||
|
|
||
| for bracket in s: | ||
| if bracket in open_to_close: | ||
| open_brackets.append(bracket) | ||
| else: | ||
| last = open_brackets.pop() | ||
|
|
||
| if not last or bracket != open_to_close[last]: | ||
| return False | ||
|
|
||
| return len(open_brackets) == 1 | ||
|
|
||
|
|
||
| solution = Solution() | ||
|
|
||
| s = "()" * 5000 | ||
|
|
||
| total_time = timeit.timeit( | ||
| lambda: solution.isValid(s), | ||
| number = 1 | ||
| ) | ||
|
|
||
| print(f"入力文字数: {len(s):,}") | ||
| print(f"合計実行時間: {total_time * 1_000_000:.3f} us") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| ## 今回解いた問題と次に解く問題 | ||
| - 今回解いた問題:20. Valid Parentheses(https://leetcode.com/problems/valid-parentheses/description/?envType=problem-list-v2&envId=xo2bgr0r) | ||
| - 次に解く問題:703. Kth Largest Element in a Stream(https://leetcode.com/problems/kth-largest-element-in-a-stream/?envType=problem-list-v2&envId=xo2bgr0r) | ||
|
|
||
| ## Step 1 | ||
| ### 考えたこと | ||
| スタックに([{が来るたびに一つずつ積んでいって、)]}が来るたびに一つずつスタックからpopしていく。スタックの名前がスタックなのは少し嫌だと思ったが、他に思いつかなかったのでとりあえずstackにした。時間計算量はO(n)、空間計算量もO(n)。 | ||
| 分岐が多くて読みづらいので、もう少し読みやすく書けないかと思った。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| stack = [] | ||
| if not s: | ||
| return True | ||
| for c in s: | ||
| if c in "([{": | ||
| stack.append(c) | ||
| elif c == ")": | ||
| if not stack: | ||
| return False | ||
| last = stack.pop() | ||
| if last == "(": | ||
| continue | ||
| else: | ||
| return False | ||
| elif c == "]": | ||
| if not stack: | ||
| return False | ||
| last = stack.pop() | ||
| if last == "[": | ||
| continue | ||
| else: | ||
| return False | ||
| elif c == "}": | ||
| if not stack: | ||
| return False | ||
| last = stack.pop() | ||
| if last == "{": | ||
| continue | ||
| else: | ||
| return False | ||
| if not stack: | ||
| return True | ||
| else: | ||
| return False | ||
| ``` | ||
| ## Step 2 | ||
| ### 読んだコード | ||
| - https://github.com/bumbuboon/Leetcode/pull/7/changes | ||
| - https://github.com/philip82148/leetcode-swejp/pull/11/changes | ||
|
|
||
| ### 考えたこと | ||
| - 先に[と]みたいにペアを作っておく。open_to_closeのような名前のdictionary型変数がいいか。 | ||
| - return(len(stack) == 0)だと可読性が高い | ||
| - スタックの名前がstackの代わりの名前として、open_bracketsなどがある。 | ||
| - if not stackの分岐を避けるためにあらかじめstackの中に番兵(Cだと\0などの目印、PythonだとNoneなどか?)を入れておくのも有効。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| open_brackets = [] | ||
| open_to_close = {'(' : ')', | ||
| '{' : '}', | ||
| '[' : ']'} | ||
| for c in s: | ||
| if c in open_to_close: | ||
| open_brackets.append(c) | ||
| elif not open_brackets: | ||
| return False | ||
| else: | ||
| last = open_brackets.pop() | ||
| if open_to_close[last] != c: | ||
| return False | ||
| return (len(open_brackets) == 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. 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. PEP 8でも同様の記述がなされていますね。 https://peps.python.org/pep-0008/
Owner
Author
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. ありがとうございます。PEP 8のほうも確認させていただきました。何度か指摘されているので、まさにソフトウェアエンジニアの常識の典型例なのかなと感じています。 |
||
| ``` | ||
| ## Step 3 | ||
| - 番兵を使って書いてみる。dictへのアクセスは結局その中にキーがあるかを確認する必要があるので、分岐の数自体は変わらないが、分岐より先にpopできるのが直感的でわかりやすい。 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def isValid(self, s: str) -> bool: | ||
| open_to_close = {'(' : ')', | ||
| '{' : '}', | ||
| '[' : ']'} | ||
| open_brackets = [None] # Put None as a sentinel | ||
| for bracket in s: | ||
| if bracket in open_to_close: | ||
| open_brackets.append(bracket) | ||
| else: | ||
| last = open_brackets.pop() | ||
| if not last or bracket != open_to_close[last]: | ||
| return False | ||
| return (len(open_brackets) == 1) # Check only the sentinel left | ||
| ``` | ||
|
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. 全体的にとても読みやすかったです。
Owner
Author
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.
実行時間を見積もるとよいと思います。
https://nuc.hatenadiary.org/entry/2025/11/29/#%E7%A7%92%E3%81%A7%E3%81%AE%E5%88%A4%E6%96%AD
Yuto729/leetcode#16 (comment)
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.
ありがとうございます!これから意識するようにしてみます。
Pythonでのこのような単純な処理であれば1回0.1us-1us程度と考えて、O(n)でsのlengthが最大10^4のため、最悪でも100us-1000usの範囲内と見積もるイメージでやってみようと思います。
実際にsのlengthを最大にして計測したところ、260usだったため見積もりの範囲内でした。