Go語言的LeetCode刷題之旅-03-無重複字符的最長子串
題目:
給定一個字符串,找出不含有重複字符的最長子串的長度。
示例:
給定 “abcabcbb” ,沒有重複字符的最長子串是 “abc” ,那麼長度就是3。
給定 “bbbbb” ,最長的子串就是 “b” ,長度是1。
給定 “pwwkew” ,最長子串是 “wke” ,長度是3。請注意答案必須是一個子串,”pwke” 是 子序列 而不是子串。
思路:
利用s[left:i+1]來表示s[:i+1]中的包含s[i]的最長子字符串。 location[s[i]]是字符s[i]在s[:i+1]中倒數第二次出現的序列號。 當left < location[s[i]]的時候,說明字符s[i]出現了兩次。需要設置 left = location[s[i]] + 1, 保證字符s[i]只出現一次。
Go代碼:
package main
func lengthOfLongestSubstring(s string) int {
// location[s[i]] == j 表示:
// s中第i個字符串,上次出現在s的j位置,所以,在s[j+1:i]中沒有s[i]
// location[s[i]] == -1 表示: s[i] 在s中第一次出現
location := [256]int{} // 只有256長是因爲,假定輸入的字符串只有ASCII字符
for i := range location {
location[i] = -1 // 先設置所有的字符都沒有見過
}
maxLen, left := 0, 0
for i := 0; i < len(s); i++ {
// 說明s[i]已經在s[left:i+1]中重複了
// 並且s[i]上次出現的位置在location[s[i]]
if location[s[i]] >= left {
left = location[s[i]] + 1 // 在s[left:i+1]中去除s[i]字符及其之前的部分
} else if i+1-left > maxLen {
// fmt.Println(s[left:i+1])
maxLen = i + 1 - left
}
location[s[i]] = i
}
return maxLen
}
總結:
利用Location保存字符上次出現的序列號,避免了查詢工作。location和Two Sum中的m是一樣的作用。
// m 負責保存map[整數]整數的序列號
m := make(map[int]int, len(nums))