华为算法题 go语言或者ptython

时间:2024-02-23 11:55:31

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。
示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。
示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

假设我们有一个字符串:s = "abcabcbb"

我们开始遍历这个字符串,使用一个“盒子”来存储不重复的字符。

  1. 我们从字符串的开头开始,第一个字符是 ‘a’,我们放入盒子中,盒子内有:[a],目前盒子的长度为1。
  2. 接着是 ‘b’,我们放入盒子中,盒子内有:[a, b],目前盒子的长度为2。
  3. 然后是 ‘c’,我们放入盒子中,盒子内有:[a, b, c],目前盒子的长度为3。
  4. 然后又是 ‘a’,在这里我们发现盒子内已经有了 ‘a’,所以我们需要重新开始计算盒子。我们将 ‘a’ 上一次出现的位置后面的字符都去掉,得到新的盒子内容为 [b, c, a],目前盒子的长度为3。
  5. 然后是 ‘b’,我们放入盒子中,盒子内有:[b, c, a],目前盒子的长度为3。
  6. 接着是 ‘c’,我们发现 ‘c’ 已经在盒子中了,所以我们需要重新开始计算盒子。我们将 ‘c’ 上一次出现的位置后面的字符都去掉,得到新的盒子内容为 [a, b, c],目前盒子的长度为3。
  7. 最后是 ‘b’,我们放入盒子中,盒子内有:[a, b, c],目前盒子的长度为3。

我们遍历完整个字符串后,最长的不含重复字符的子串就是 “abc”,它的长度为 3。

package main

import "fmt"
// start 和 i 分别表示当前不含重复字符的子串的起始位置和结束位置。lastI 表示字符上一次出现的位置。

func lengthOfLongestSubstring(s string) int {
	// 使用 map 存储字符最后出现的位置
	lastOccurred := make(map[byte]int)
	start, maxLength := 0, 0

	// 遍历字符串
	for i, ch := range []byte(s) {
		// 如果字符已经出现过,并且出现位置在当前子串中
		if lastI, ok := lastOccurred[ch]; ok && lastI >= start {
			start = lastI + 1 // 更新子串起始位置
		}
		// 更新字符最后出现的位置
		lastOccurred[ch] = i
		// 更新最大子串长度
		if i-start+1 > maxLength {
			maxLength = i - start + 1
		}
	}
	return maxLength
}

func main() {
	s1 := "abcabcbb"
	fmt.Println(lengthOfLongestSubstring(s1))
}