-
Notifications
You must be signed in to change notification settings - Fork 0
3. Longest Substring Without Repeating Characters #50
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,177 @@ | ||
| # Step1 | ||
|
|
||
| かかった時間:15min | ||
|
|
||
| 計算量: | ||
|
|
||
| 文字列の長さをNとして | ||
| - 時間計算量:O(N) | ||
| - 空間計算量:O(N) | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| start = 0 | ||
| stop = 1 | ||
|
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.
|
||
| substring_chars = set() | ||
| longest_substring_len = 0 | ||
| while stop <= len(s): | ||
| c = s[stop - 1] | ||
|
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. 好みの範疇かもしれませんが、stop (last) のほうが、それを含まないインデックスであるというのは少し違和感があります。 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. こういうコメントを頂いた背景があります。 |
||
| while c in substring_chars: | ||
| substring_chars.remove(s[start]) | ||
| start += 1 | ||
|
|
||
| substring_chars.add(c) | ||
| longest_substring_len = max( | ||
| longest_substring_len, | ||
| stop - start | ||
| ) | ||
| stop += 1 | ||
|
|
||
| return longest_substring_len | ||
| ``` | ||
| 思考ログ: | ||
| - 文字列を延ばしていって、現在の部分文字列に重複が出たら、重複が解消されるまで頭を進める、を文字列の終わりまで繰り返す | ||
|
|
||
| # Step2 | ||
|
|
||
| 講師役目線でのセルフツッコミポイント: | ||
| - ```while stop < len(s): stop += 1```は、for文に直そうという気持ちになってほしい | ||
|
|
||
| 参考にした過去ログなど: | ||
| - https://github.com/ryosuketc/leetcode_arai60/pull/37 | ||
| - https://github.com/Kaichi-Irie/leetcode-python/pull/9 | ||
| - 出現した最後のインデックスを覚えておく | ||
| - https://github.com/yakataN/Arai60/pull/3 | ||
| - https://github.com/skypenguins/coding-practice/pull/3 | ||
| - https://github.com/fuga-98/arai60/pull/47 | ||
| - https://github.com/hroc135/leetcode/pull/45 | ||
| - https://github.com/olsen-blue/Arai60/pull/49 | ||
| - https://github.com/olsen-blue/Arai60/pull/49#discussion_r2005295464 | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/52 | ||
| - 文字種類の制限から全探索の計算量はもう少し絞れる | ||
| - https://github.com/Ryotaro25/leetcode_first60/pull/52#discussion_r1981068549 | ||
| - https://github.com/katsukii/leetcode/pull/5 | ||
| - 出現回数を記録していってもいい | ||
| - https://github.com/katsukii/leetcode/pull/5/files#r1896477073 | ||
| - https://github.com/philip82148/leetcode-swejp/pull/3 | ||
| - スタック&ヒープについて | ||
| - https://github.com/philip82148/leetcode-swejp/pull/3/files#r1853944201 | ||
| - https://github.com/Yoshiki-Iwasa/Arai60/pull/42 | ||
| - https://github.com/rihib/leetcode/pull/7 | ||
| - https://github.com/rossy0213/leetcode/pull/23 | ||
| - https://github.com/rossy0213/leetcode/pull/23#discussion_r1696208116 | ||
| - https://github.com/fhiyo/leetcode/pull/48 | ||
| - leftをexclusiveにするのも一つ | ||
| - setのドキュメント | ||
| - https://docs.python.org/3.12/library/stdtypes.html#set | ||
| - https://github.com/sakzk/leetcode/pull/3 | ||
| - https://github.com/sakzk/leetcode/pull/3/files#r1591194013 | ||
| - https://github.com/Mike0121/LeetCode/pull/21 | ||
| - https://github.com/Exzrgs/LeetCode/pull/2 | ||
| - https://github.com/thonda28/leetcode/pull/6 | ||
| - https://github.com/SuperHotDogCat/coding-interview/pull/3 | ||
| - https://github.com/nittoco/leetcode/pull/3 | ||
| - ASCIIについて | ||
| - https://discordapp.com/channels/1084280443945353267/1198621745565937764/1211683153668866139 | ||
| - https://github.com/t0d4/leetcode/pull/2 | ||
| - https://github.com/shining-ai/leetcode/pull/48 | ||
| - https://github.com/hayashi-ay/leetcode/pull/47 | ||
| - https://discord.com/channels/1084280443945353267/1198621745565937764/1211678975156420678 | ||
| - ASCIIの話 | ||
| - https://github.com/usatie/leetcode/blob/main/Blind75/03.%20Longest%20Palindromic%20Substring/ans_01_20240126.cpp | ||
|
|
||
| 全探索 | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| def is_repeating(s: str) -> bool: | ||
| return len(set(s)) != len(s) | ||
|
|
||
| s_len = len(s) | ||
| longest_substring_len = 0 | ||
| for left in range(s_len): | ||
| for right in range(left, s_len): | ||
|
Comment on lines
+93
to
+94
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. #35 (comment) 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. ハンガリアン記法的な話ですね
Comment on lines
+93
to
+94
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. s_lenと変数を作るより普通にlen(s)のままの方がわかりやすく思います |
||
| sub_s = s[left:right + 1] | ||
|
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. ここでリストのコピーを作ることになるので非効率ではありますね |
||
| if not is_repeating(sub_s): | ||
| longest_substring_len = max( | ||
| longest_substring_len, | ||
| len(sub_s) | ||
| ) | ||
|
|
||
| return longest_substring_len | ||
| ``` | ||
| 思考ログ: | ||
| - 頭から抜けていた、良くない | ||
|
|
||
| 出現回数管理 | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| letter_to_count = {c: 0 for c in s} | ||
|
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. defaultdict とか Counter を使いたくなります |
||
|
|
||
|
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. 意味がないですね。 |
||
| left = 0 | ||
| max_len = 0 | ||
| for right in range(len(s)): | ||
| while letter_to_count[s[right]] > 0: | ||
| letter_to_count[s[left]] -= 1 | ||
| left += 1 | ||
|
|
||
| letter_to_count[s[right]] += 1 | ||
| max_len = max(max_len, right - left + 1) | ||
|
Comment on lines
+120
to
+121
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つの行逆にします。(for文の最後でrightが進むことに関係する部分は動かしたいため)
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. 確かにそうですね。 |
||
|
|
||
| return max_len | ||
| ``` | ||
| 思考ログ: | ||
| - これはこれで素直だなと感じた | ||
|
|
||
| 文字が登場した最後のインデックスを使う | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| left = 0 | ||
| letter_to_last_index = {} | ||
| max_len = 0 | ||
| for right in range(len(s)): | ||
| if s[right] in letter_to_last_index: | ||
| left = max(left, letter_to_last_index[s[right]] + 1) | ||
|
|
||
| max_len = max(max_len, right - left + 1) | ||
|
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. 最大の長さであることはは読んでいれば割とすぐわかる情報で、むしろresultの方が何についての最大の長さなのか関数名を見ればわかるので(関数名がはっきりしていたら)、個人的には好みです |
||
| letter_to_last_index[s[right]] = right | ||
|
|
||
| return max_len | ||
| ``` | ||
| 思考ログ: | ||
| - ややテクニカルだが効率はいいなと感じた | ||
|
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. 自分には、最後に見たインデックス情報を活用するこの方法がすぐ出てきませんでした。。 精進致します。 |
||
| - leftを更新する際に現在の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. 私もハマりました |
||
| - ちゃんと脳内でシミュレート出来ていれば問題ないのかもしれないが、自分のシミュレータだとちょっと危なっかしいなと感じた | ||
|
|
||
| # Step3 | ||
|
|
||
| かかった時間:4min | ||
|
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. これ 3 回やって 4 min ですかね?突っ込むほどのこともないですが、もうちょっと早くなる気もしており、いや別に早くすることが目的ではないんですが、なにか迷いがあるのかなあ、と思いました。
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. 確かにと思い、解き直してみましたが、2分程かかりました。 |
||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| letter_to_last_index = {} | ||
| left = 0 | ||
| max_len = 0 | ||
| for right in range(len(s)): | ||
| if s[right] in letter_to_last_index: | ||
| left = max(left, letter_to_last_index[s[right]] + 1) | ||
|
|
||
| max_len = max(max_len, right - left + 1) | ||
| letter_to_last_index[s[right]] = right | ||
|
|
||
| return max_len | ||
| ``` | ||
| 思考ログ: | ||
| - 情報の活用の仕方に学びがあったので、こちらの解き方にした | ||
| - step2から少し日が経って書いたが、ほぼ同じものが出てきて、改めてそういうものなんだなと感じた | ||
| - 序盤の変数定義の並びが変わっているのは、この方法で解こうという思いが強かったからかもしれない | ||
|
|
||
| # Step4 | ||
|
|
||
| ```python | ||
| ``` | ||
| 思考ログ: | ||
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.
かなり前のPRへのコメントで恐縮ですが、この問題の制約に
とあるので、入力の文字列がめちゃめちゃ大きくなったとしても、
substringはあるサイズで頭打ちになる -> 空間計算量はO(1)な気がします。