Skip to content

Commit e95c3ba

Browse files
authored
Merge pull request #7 from rihib/longest_substring_without_repeating_characters
Longest Substring Without Repeating Characters
2 parents f5f5188 + 5b61f41 commit e95c3ba

File tree

4 files changed

+87
-0
lines changed

4 files changed

+87
-0
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package longestsubstringwithoutrepeatingcharacters
3+
4+
/*
5+
時間:34分
6+
最初に下記のやり方でやることを思いついたが、もう少し賢いやり方があるのではないかと10分ぐらい考えてしまい、思いつかなかったので、とりあえず書こうと思い、書きました。結果的には他の人のコードも見たりする限り、この方法で良かったのだとわかりました。
7+
*/
8+
func lengthOfLongestSubstring_step1(s string) int {
9+
maxLen := 0
10+
head := 0
11+
m := make(map[rune]struct{})
12+
for tail := 1; tail <= len(s); tail++ {
13+
if _, ok := m[rune(s[tail-1])]; ok {
14+
for s[head] != s[tail-1] {
15+
delete(m, rune(s[head]))
16+
head++
17+
}
18+
head++
19+
} else {
20+
m[rune(s[tail-1])] = struct{}{}
21+
}
22+
substring := s[head:tail]
23+
maxLen = max(maxLen, len(substring))
24+
}
25+
return maxLen
26+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package longestsubstringwithoutrepeatingcharacters
3+
4+
/*
5+
より変数名をわかりやすくし、無駄な部分を消しました。
6+
*/
7+
func lengthOfLongestSubstring(s string) int {
8+
maxLen, head := 0, 0
9+
inUse := make(map[byte]struct{})
10+
for tail := range s {
11+
if _, ok := inUse[s[tail]]; ok {
12+
for s[head] != s[tail] {
13+
delete(inUse, s[head])
14+
head++
15+
}
16+
head++
17+
} else {
18+
inUse[s[tail]] = struct{}{}
19+
}
20+
maxLen = max(maxLen, tail-head+1)
21+
}
22+
return maxLen
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package longestsubstringwithoutrepeatingcharacters
3+
4+
/*
5+
inUseの値にbool値を入れればよりシンプルに書けると思ったので、書き換えました。
6+
7+
- inUseの値に最後に見たインデックスを入れることも考えたが、どちらにせよ`delete(inUse, s[head])`でそこまでの文字を消していく必要があるので、意味がないのでは?
8+
- head, tailか、left, rightのどちらの方がベターか。substringの先頭・末尾と捉えるのであれば前者、Two Pointersと捉えるのであれば後者?head, tailの方がinclusiveだとわかるのでより良いのでは?(https://github.com/sakzk/leetcode/pull/3#discussion_r1591191532)
9+
- inUseという変数名はどうか?
10+
ー 確かにsliding windowと捉えることもできる(https://github.com/sakzk/leetcode/pull/3#discussion_r1591194013)
11+
*/
12+
func lengthOfLongestSubstring_step3(s string) int {
13+
maxLen, head := 0, 0
14+
inUse := make(map[byte]bool)
15+
for tail := range s {
16+
for inUse[s[tail]] {
17+
delete(inUse, s[head])
18+
head++
19+
}
20+
inUse[s[tail]] = true
21+
maxLen = max(maxLen, tail-head+1)
22+
}
23+
return maxLen
24+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//lint:file-ignore U1000 Ignore all unused code
2+
package longestsubstringwithoutrepeatingcharacters
3+
4+
func lengthOfLongestSubstring_step4(s string) int {
5+
maxLength, left, seen := 0, 0, make(map[rune]int)
6+
for right, r := range s {
7+
if lastIndex, ok := seen[r]; ok && lastIndex >= left {
8+
left = lastIndex + 1
9+
}
10+
seen[r] = right
11+
maxLength = max(maxLength, right-left+1)
12+
}
13+
return maxLength
14+
}

0 commit comments

Comments
 (0)