無重複字元的最長子串
這是 LeetCode 第三題,題幹如下:
給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。
示例 1:
輸入: “abcabcbb”
輸出: 3
解釋: 因為無重複字元的最長子串是 “abc”,所以其長度為 3。
示例 2:
輸入: “bbbbb”
輸出: 1
解釋: 因為無重複字元的最長子串是 “b”,所以其長度為 1。
示例 3:
輸入: “pwwkew”
輸出: 3
解釋: 因為無重複字元的最長子串是 “wke”,所以其長度為 3。請注意,你的答案必須是 子串 的長度,”pwke” 是一個子序列,不是子串。
解題思路
常規思路:兩層迴圈字串,並且我們需要一個 Map字典 來標記哪些字元已經出現過,流程如下:
GO語言的程式碼實現:
func lengthOfLongestSubstring(s string) (length int) {
if "" == s {
return
}
length = 1
for i := 0; i < len(s); i++ {
// 字元的ASCII範圍在0-127,所以這裡申明瞭map的key型別為uint8
dict := make(map[uint8]bool)
dict[s[i]] = true
for j := i + 1; j < len(s); j++ {
// 判斷字元是否在map中,如果存在就直接跳出迴圈
if _, ok := dict[s[j]]; ok {
break
}
// 將字元放入map中
dict[s[j]] = true
// 每次都計算最大值
cMax := j - i + 1
if cMax > length {
length = cMax
}
}
}
return
}
這個題目,其實主要的考點在於對 滑動視窗 的理解。
滑動視窗:滑動視窗是陣列、字串問題中常用的抽象概念。
視窗通常是在陣列、字串中由開始和結束索引定義的一系列元素的集合,即 [i, j)(左閉,右開)。
而滑動視窗是可以將兩個邊界向某一方向“滑動”的視窗。例如,我們將 [i, j) 向右滑動 1 個元素,
則它將變為 [i+1, j+1)[i+1,j+1)(左閉,右開)。
那麼借用 滑動視窗 的概念,如何來解題呢?我這裡畫了一張示意圖,其中 [X,Y) 就是 滑動視窗:
這裡有一個注意點:當 Y 指向的字元在 [X,Y) 滑動視窗之間時,假設索引值為 index,這時候 X 是直接移動到 index+1 的位置。
GO語言的程式碼實現:
func lengthOfLongestSubstring(s string) int {
var Length int
var s1 string
x := 0
y := 0
s1 = s[x:y]
for ; y < len(s); y++ {
// strings.IndexByte 用於判斷y對應的字元是否在[x,y)中,不存在返回-1
if index := strings.IndexByte(s1, s[y]); index != -1 {
// 如果存在的話,x直接跳到index的後一位
x += index + 1
}
s1 = s[x : y+1]
if len(s1) > Length {
Length = len(s1)
}
}
return Length
}
總結
每天進步一點點,加油!
完整程式碼:https://github.com/wx-satellite/go-leetcod…
本作品採用《CC 協議》,轉載必須註明作者和本文連結