Go語言的LeetCode刷題之旅-003-無重複字符的最長子串

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))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章