Leetcode Note: Go - Longest Substring Without Repeating Characters
Longest Substring Without Repeating Characters - LeetCode
https://leetcode.com/problems/longest-substring-without-repeating-characters/
- Go 言語で取り組んだメモ
所感
- 繰り返しが存在しているのかチェックする実装方法が思いつかない…
実装準備
func lengthOfLongestSubstring(s string) int {
output := 0
if s == nil {
return output
}
// うーん。どうやってユニークな文字か判定すれば良いんだろう
// 前後の文字をチェックしても xxxabcxxxdefxxx みたいなパターンを検出できない
for i := 0; i < len(s); i++ {
}
return output
}
func main() {
input := "abcabcbb" // output: abc => 3
// input := "bbbbb" // output: b => 1
// input := "pwwkew" // output: kew => 3
fmt.Println(input)
output := lengthOfLongestSubstring(input)
fmt.Println(output)
}回答
Golang: explanation (100% speed & memory) - LeetCode Discuss
https://leetcode.com/problems/longest-substring-without-repeating-characters/discuss/441906/Golang%3A-explanation-(100-speed-and-memory)
dictは以前に遭遇した文字のディクショナリiをインクリメントしてs[i]をdictのインデックスとして使用して、値を true にするdict[s[i]] = true- これを既出の文字列か判定するためのマークにする
- 各ステップで
lengthをインクリメントしてmaxとして比較して、長さが大きくなった場合はmax = lengthを設定 - すでに
dictでマークした文字をdict[s[i]] == trueで判定した場合は、 2つ目 のイテレーターであるjをインクリメントしてディクショナリdict[s[j]] = falseでマークを外して、dict [s[i]] == falseの間 length をデクリメントするdict[s[i]] == trueなら既出の文字列なので、その処理を行う- 文字数をカウントしている
lengthのデクリメント dict[s[j]] = falseで既出の文字列と判定しないようにマーク外し
i < len(s)の間、ステップ 2 - 4 を繰り返すfunc lengthOfLongestSubstring(s string) int { dict := [128]bool{} length, max := 0, 0 for i, j := 0, 0; i < len(s); i++ { index := s[i] if dict[index] { for ;dict[index]; j++ { length-- dict[s[j]] = false } } dict[index] = true length++ if length > max { max = length } } return max }
- for 文で複数のイテレーターを定義して使うという方法があるのか・・・!
for i, j := 0, 0; i < len(s); i++ {}
- bool 配列をディクショナリとして使って、既出のパターンを検知するのも目からウロコ
- Go 言語における bool のゼロ値は false なので、デフォルトで false が入っている
- for loop はシンプルに回しつつも、カウントしたい値は for loop のスコープ外で定義しておき、複数のイテレーターを使って処理する
難しい!