题目描述
中等
提示
给定一个字符串 s ,请你找出其中不含有重复字符的最长子串的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列, 不是子串。
提示:
0 <= s.length <= 5 * 104s由英文字母、数字、符号和空格组成
解题思路
使用滑动窗口遍历所有不重复字符的子串,从而得到最长无重复的子串。
规则1:为了性能考虑使用大小为126的数组记录字符出现的最后位置。
规则2:在遍历一个新字符时,如果这个字符已经出现过就将start更新为这个字符最后出现的位置+1(左窗口滑动),如果这个字符从未出现则向右继续滑动窗口。
代码(哈希表(整型数组))
存储字符出现的最后位置
func lengthOfLongestSubstring(s string) int {
charPosition := make([]int, 128)
for i := range charPosition {
charPosition[i] = -1
}
start := 0
maxLength := 0
for i := 0; i < len(s); i++ {
ch := s[i]
if lastPos := charPosition[ch]; lastPos >= start {
start = lastPos + 1
}
currentLength := i - start + 1
maxLength = max(maxLength, currentLength)
charPosition[ch] = i
}
return maxLength
}
存储字符出现次数
func lengthOfLongestSubstring(s string) int {
charCounts := make([]int, 128)
start := 0
maxLength := 0
for i := 0; i < len(s); i++ {
charCounts[s[i]]++
for charCounts[s[i]] > 1 {
charCounts[s[start]]--
start++
}
currentLength := i - start + 1
maxLength = max(maxLength, currentLength)
}
return maxLength
}
代码(使用map记录每个字符最后出现的位置)
func lengthOfLongestSubstring(s string) int {
// 使用map记录每个字符最后出现的位置
charPosistion := make(map[rune]int)
start := 0
maxLength := 0
// 使用for-range遍历字符串中的所有rune字符
for i, char := range s {
// 如何字符已经在当前窗口中出现过,更新start指针
if lastPos, exists := charPosistion[char]; exists && lastPos >= start {
start = lastPos+1
}
// 更新最大长度
currentLength := i - start + 1
if currentLength > maxLength {
maxLength = currentLength
}
// 记录字符位置
charPosistion[char] = i
}
return maxLength
}
// 1. 使用rune类型作为map键,可以处理任何Unicode字符
// 2. 记录同一个字符串上一次出现的最后位置,避免多次移动start指针
// 3. sMap命令不够直观,使用更具有描述性的 charPositions
代码(使用布尔数组记录窗口内出现的元素)
func lengthOfLongestSubstring(s string) int {
charOccurence := make([]bool, 128)
start, maxLength := 0, 0
for i := 0; i < len(s); i++ {
for charOccurence[s[i]] {
charOccurence[s[start]] = false
start++
}
charOccurence[s[i]] = true
maxLength = max(maxLength, i-start+1)
}
return maxLength
}