-
Notifications
You must be signed in to change notification settings - Fork 0
3. Longest Substring Without Repeating Characters #3
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,113 @@ | ||
| # 3. Longest Substring Without Repeating Characters | ||
| * 問題リンク: https://leetcode.com/problems/longest-substring-without-repeating-characters/ | ||
| * 使用言語: Python3 | ||
|
|
||
| ## Step1 | ||
| * Set型で重複しない文字の集合を取得しようと思ったが、subsequenceになってしまうのでこれは使えない | ||
| * 方針 | ||
| 1. 文字列sの先頭から1文字ずつ末尾に向かってポインタを動かしていく、1文字ずつsubstringに追加 | ||
| 2. ポインタの指す1文字がsubstringに含まれていたら、ポインタを1つ戻し、substringをクリアする | ||
|
|
||
| ### 以下は動かないコード | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| substring_length = 0 | ||
| substring = '' | ||
| tail = 0 | ||
| while tail != len(s)-1: | ||
| substring_length = max(substring_length, len(substring)) | ||
| substring += s[tail] | ||
|
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. こういう話題もあったので共有します。 |
||
| tail += 1 | ||
| if s[tail] in substring: | ||
| tail -= 1 | ||
| substring = s[tail] | ||
| return substring_length | ||
| ```` | ||
|
|
||
| * 実行時間: TLE | ||
|
|
||
| * いつまで経っても `tail` == `len(s)-1` とならないため、TLEとなった | ||
| - 上記原因が分からず、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. tail -= 1 してますからね。 頭の中のシミュレーターの精度を上げましょう。それと、「人が手でやるとしたらどうするか」と「複数人でシフトを組んでやってもらうとしたらどうするか」を考えてみるといいかと思います。 |
||
|
|
||
| ### 以下は動くコード | ||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| left_i = 0 | ||
| max_substring_length = 0 | ||
| char_set = set() | ||
|
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. 変数名に型名を入れてもあまり情報は増えないため、入れないほうがよいと思います。 |
||
|
|
||
| for right_i in range(len(s)): | ||
| while s[right_i] in char_set: | ||
| char_set.remove(s[left_i]) | ||
| left_i += 1 | ||
|
|
||
| char_set.add(s[right_i]) | ||
| max_substring_length = max(max_substring_length, right_i - left_i + 1) | ||
|
|
||
| return max_substring_length | ||
| ``` | ||
|
|
||
| * 実行時間: 19ms | ||
| * メモリ使用量: 17.78MB | ||
| * 時間計算量: O(n) | ||
| * 空間計算量: O(1) | ||
| * 解答時間: 5:29 | ||
|
|
||
| * 自分の考えていたアルゴリズムに近いが、`tail` を戻す考え方ではなく先頭(左側)を指すポインタを導入する考え方 | ||
| * 答えでは Set型を使っていたが、和集合の目的でSet型を使っていたわけではなく単なるハッシュテーブルとして使っている | ||
| - Set型はCPythonでは順序は保証されていないっぽいのでListが望ましい? | ||
| - cf. https://stackoverflow.com/a/61467874 | ||
|
|
||
| ## Step2 | ||
| ### 参考にした方々 | ||
| * https://github.com/fuga-98/arai60/pull/47/files/5bb14a8b628a0edf65223ebef947b3a87d745767 | ||
| - `s == 0`の場合は特に考えていなかった | ||
| - keyに文字、valueにインデックスを持つDictを作成し、そのDictで重複文字が存在するか判定 | ||
| * https://github.com/olsen-blue/Arai60/pull/49/files | ||
| - 同じアルゴリズム。動的計画法の一種でSliding Window(スライディングウィンドウ、尺取法)と呼ぶらしい | ||
| - `seen_char` の方がより実態を表していると思った | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| left_i = 0 | ||
| max_substring_length = 0 | ||
| seen_char_set = set() | ||
|
|
||
| for right_i in range(len(s)): | ||
| while s[right_i] in seen_char_set: | ||
| seen_char_set.remove(s[left_i]) | ||
| left_i += 1 | ||
|
|
||
| seen_char_set.add(s[right_i]) | ||
| max_substring_length = max(max_substring_length, right_i - left_i + 1) | ||
|
|
||
| return max_substring_length | ||
| ``` | ||
| * 解答時間: 3:01 | ||
|
|
||
| # Step3 | ||
|
|
||
| ```python | ||
| class Solution: | ||
| def lengthOfLongestSubstring(self, s: str) -> int: | ||
| left_i = 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. 以前以下のようなコメントをいただいた事があります。 |
||
| max_substring_length = 0 | ||
| seen_char_set = set() | ||
|
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. 個人的にはseenだと一度見たものは取り除かれないみたいな風に見えてしまうかもしれないので、containing_char_setとかでもいいと思います。 |
||
|
|
||
| for right_i in range(len(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. (コメントが保留中のまま送れませんでした、失礼しました…) |
||
| while s[right_i] in seen_char_set: | ||
| seen_char_set.remove(s[left_i]) | ||
| left_i += 1 | ||
|
|
||
| seen_char_set.add(s[right_i]) | ||
| max_substring_length = max(max_substring_length, right_i - left_i + 1) | ||
|
|
||
| return max_substring_length | ||
| ``` | ||
| * 解答時間 | ||
| - 1回目: 3:12 | ||
| - 2回目: 3:12 | ||
| - 3回目: 4:14 | ||
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.
-の両側にスペースを空けることをお勧めします。