滑动窗口使用场景|刷题打卡

601 阅读2分钟

滑动窗口使用场景:一般需要遍历整个数组/字符串,找出符合条件的子集。

滑动窗口使用方法:如下图。我们需要2个下标来标记窗口的边界值,决定窗口的大小。因为要找到符合条件的最值,所以每一次窗口滑动都需要记录一下符合要求的值,直到滑到末端,我们取其中符合条件的最值。

一、题目描述

LeetCode 3.无重复字符的最长子串

示例 1:

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

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

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

二、思路分析

根据介绍的滑动窗口,我们应用到本题中

滑动窗口的边界值:x, j

if 出现重复字符

​ 窗口左边界向右移动

​ 计算此时的最值

else

​ 窗口右边界向右移动

​ 计算此时的最值

三、AC代码
func lengthOfLongestSubstring(s string) int {
    // 边界值
	if s == " " {
		return 1
	}
	lenStr := len(s)
	var maxLen int // 最大长度值
	var x, j int  // 滑动窗口的边界值
	for j < lenStr { // 判断滑动窗口是否已经到边界
		if strings.Contains(s[x:j], string(s[j])) {  // 有重复字符出现
			x = x + 1  // 窗口左边界向右移动一个单位
			if len(s[x:j+1]) > maxLen {  // 此时计算最值
				maxLen = len(s[x : j+1])
			}
		} else {
			j++ // 窗口右边界扩大
			if len(s[x:j]) > maxLen {
				maxLen = len(s[x:j]) // 此时计算最值
			}
		}
	}
	return maxLen
}
四、总结

滑动窗口原理很容易理解,主要难点在于对于给定条件,怎么找出最优值。我们可以再练练手

同系列题目:

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3] 输出:2 解释:子数组 [4,3] 是该条件下的长度最小的子数组。

AC代码:

func minSubArrayLen(target int, nums []int) int {
	lenNums := len(nums)
	var i, j, ans, minCnt int
	minCnt = lenNums + 1
	for j < lenNums {
		ans = nums[j] + ans
		if ans >= target {
			if j-i+1 < minCnt {
				minCnt = j - i + 1
			}
			ans = 0
			i++
			j = i - 1
		}
		j++
	}
	if minCnt == lenNums+1 {
		minCnt = 0
	}
	return minCnt
}

LeetCode159. 至多包含两个不同字符的最长子串

输入:s = "abccbca"

输出:5

// 滑动窗口 使用map标记哪个字符被遍历到
func ContainsTweChar(s string) int {
	var charMap map[string]int
	charMap = make(map[string]int)
	var lenS = len(s)
	var i, j int
	j++
	var maxCnt int
	for j < lenS {
		charMap[s[i:i+1]] = i
		if strings.Contains(s[i:j+1], string(s[j])) {
			charMap[s[j:j+1]] = j
		}
		if len(charMap) > 2 {
			delete(charMap, s[i:i+1])
			i++
		}
		j++
		if maxCnt < len(s[i:j]) {
			maxCnt = len(s[i:j])
		}
	}
	return maxCnt
}
  • 本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情