算法學習之路----無重複字符的最長子串

無重複字符的最長子串

這是 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…

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