滑动窗口

110 阅读2分钟

image.png 滑动窗口是一种常见的用于解决字符串、数组相关问题的算法思想,特别适合用于处理子串、子数组问题。对于这个问题,滑动窗口能够帮助我们维护一个没有重复字符的子串,并在遍历字符串的过程中不断调整窗口的大小来寻找最长的无重复字符子串。

  1. 初始化:定义两个指针leftright,分别表示滑动窗口的左右边界。窗口内是当前考虑的子串。

  2. 扩展窗口:移动right指针遍历字符串,将right指向的新字符加入当前考虑的子串中。

  3. 窗口内无重复检查:在每次移动right指针时,检查新加入的字符是否已经存在于当前子串中。

    • 如果新字符未重复,更新最长无重复子串的长度。
    • 如果新字符重复,移动left指针直到子串中不包含重复的新字符。
  4. 更新最大长度:在每次迭代中,更新无重复字符子串的最大长度。

这段代码通过维护一个字符到出现次数的映射(即window),在遍历字符串的过程中动态地调整滑动窗口的大小。这样,我们就可以在O(n)的时间复杂度内找到无重复字符的最长子串的长度。

func lengthOfLongestSubstring(s string) int {
	left, right, maxLength := 0, 0, 0 //左闭右开[left,right)
	m := make(map[byte]int)
	for right < len(s) {
		val := s[right]
		m[val]++
		right++ //正是这里右给right++了,所以下面不用再+1

		//判断重复,注意判断的不是右移后的新字符
		for m[val] > 1 {
			//左指针右移
			//m[val]-- 这里应该是左指针对应的数据--
			leftVal := s[left]
			m[leftVal]--
			left++
		}

		if maxLength < right-left {
			maxLength = right - left //这里不用再+1
		}
	}
	return maxLength
}