diff --git a/3. Longest Substring Without Repeating Characters/3. Longest Substring Without Repeating Characters.md b/3. Longest Substring Without Repeating Characters/3. Longest Substring Without Repeating Characters.md new file mode 100644 index 0000000..1af7064 --- /dev/null +++ b/3. Longest Substring Without Repeating Characters/3. Longest Substring Without Repeating Characters.md @@ -0,0 +1,82 @@ +# 3. Longest Substring Without Repeating Characters +## STEP1 +- 何も見ずに解いてみる +- 始点と終点を進めていく過程で文字のカウントをしておく。重複しない限り終点を先に進めて重複した時点で長さを取得。 +```python +import collections + + +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + longest_length = 0 + + end_index = 0 + characters = collections.defaultdict(int) + for start_index in range(len(s)): + while end_index < len(s) and characters[s[end_index]] == 0: + characters[s[end_index]] = 1 + end_index += 1 + longest_length = max(longest_length, end_index - start_index) + + characters[s[start_index]] -= 1 + return longest_length +``` + +## STEP2 +### プルリクやドキュメントを参照 +- https://github.com/olsen-blue/Arai60/pull/49/files + - 重複しないように index を進めているので、考慮している範囲の文字の出現回数は 0, 1 であり、set で管理することで十分。 + - right を順に進めることもできる。重複した文字が出た際の挙動はこちらの方がわかりやすい。 +right を進める書き方 +```python +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + longest_length = 0 + left_index = 0 + characters = set() + for right_index in range(len(s)): + while s[right_index] in characters: + characters.remove(s[left_index]) + left_index += 1 + characters.add(s[right_index]) + longest_length = max(longest_length, right_index - left_index + 1) + return longest_length +``` +- https://github.com/hayashi-ay/leetcode/pull/47/files + - 見たことがある文字の index を管理することで、範囲の更新が効率的になる。 +```python +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + longest_length = 0 + left_index = 0 + letter_to_index = {} + for right_index in range(len(s)): + if s[right_index] in letter_to_index: + left_index = max(left_index, letter_to_index[s[right_index]] + 1) + letter_to_index[s[right_index]] = right_index + longest_length = max(longest_length, right_index - left_index + 1) + return longest_length +``` +- https://github.com/olsen-blue/Arai60/pull/49/files#r2005295464 + - 条件分岐せずに書く方法。読む難易度は若干上がるので自分では書かない気がします。ただ、現状は get 使う方法が選択肢に入っていないので良くない。 +left_index = max(left_index, letter_to_index.get(s[right_index], -1) + 1) + +## STEP3 +### 3回ミスなく書く +set で重複管理する方法がファーストチョイスと思いました。 +```python +class Solution: + def lengthOfLongestSubstring(self, s: str) -> int: + longest_length = 0 + left = 0 + letters_in_window = set() + for right in range(len(s)): + while s[right] in letters_in_window: + letters_in_window.remove(s[left]) + left += 1 + letters_in_window.add(s[right]) + longest_length =max(longest_length, right - left + 1) + return longest_length +``` + +2分,2分,1分で3回Accept