一、滑动窗口
- 本质:固定左端点,不断枚举右端点, 不满足条件时缩短左端点。
- 题目条件:满足 单调性(数组元素都是正数) 的 子数组(数组元素连续) 。
二、思路
-
关键词:
- 子串/子数组必定连续,且单调性(即同为正数)
- 求长度最长、频率最高、数目最多等
-
难点在于:
- 使用if还是for
- 最值结果通常是right-left+1来更新
- 统计数目使用map
三、题目汇总
- 3. 无重复字符的最长子串
- 395. 至少有 K 个重复字符的最长子串
- 1208. 尽可能使字符串相等
- 643. 子数组最大平均数 I
- 1423. 可获得的最大点数
- 1838. 最高频元素的频数
- 904. 水果成篮
- 424. 替换后的最长重复字符
- 1052. 爱生气的书店老板
- 1610. 可见点的最大数目
四、题解汇总
- Code 3
- “不含有重复字符”,即可使用map。
- “最长子串”,“子串”即连续,子串可想到滑动窗口,使用两指针,“最长”,即可定义一个变量存储最值,持续更新。
func lengthOfLongestSubstring(s string) int {
maxLen:=0 // 定义一个变量存储最值
strsMap:=map[byte]int{} // “不含有重复字符”,即可使用map
left:=0
for i:=0;i<len(s);i++{
strsMap[s[i]]++ // 扩张窗口
for strsMap[s[i]]>1{ // 收缩窗口的条件:一旦含有重复子串,即可收缩,左移指针
strsMap[s[left]]--
left++
}
maxLen=max(maxLen,i-left+1) // 更新最值,只要走到这里均满足无重复字符串
}
return maxLen
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
- code 395
- “每一字符出现次数都不少于k”,即可使用map,key为字符,value为字符个数。
- “最长子串”,“子串”即连续,子串可想到滑动窗口,使用两指针,“最长”,即可定义一个变量存储最值,持续更新。
func longestSubstring(s string, k int) int {
if len(s)==0{
return 0
}
maxLen:=0
dic:=map[int]int{}
for i:=0;i<len(s);i++{
ch:=int(s[i]-'a')
dic[ch]++
}
var splits byte
for ch,v:=range dic{
if v>0 && v<k{
splits=byte(ch)+'a'
break
}
}
if splits==0{
return len(s)
}
for _,v:=range strings.Split(s,string(splits)){
maxLen=Max(maxLen,longestSubstring(v,k))
}
return maxLen
}
func Max(a,b int)int{
if a>b{
return a
}
return b
}
- code 1208
- “s的子字符串转化为它在t中对应的子字符串”,“转换”,即判断s和t是否相等,“子字符串”即连续,子串可想到滑动窗口,使用两指针
- “最大长度”,“最长”,即可定义一个变量存储最值,持续更新。
func equalSubstring(s string, t string, maxCost int) int {
maxLen:=0
left:=0
n:=len(s)
sum:=0
for right:=0;right<n;right++{
diff:=int(s[right])-int(t[right])
sum=sum+abs(diff)
for sum>maxCost{
diff:=int(s[left])-int(t[left])
sum=sum-abs(diff)
left++
}
maxLen=max(maxLen,right-left+1)
}
return maxLen
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
func abs(a int)int{
if a<0{
return -a
}
return a
}
- code 643
func findMaxAverage(nums []int, k int) float64 {
var maxValue float64
var sum float64
for i:=0;i<k;i++{
sum=sum+float64(nums[i])
}
maxValue=sum/float64(k)
for i:=0;i<len(nums)-k;i=i+1{
sum=sum-float64(nums[i])
sum=sum+float64(nums[i+k])
maxValue=MaxFloat(maxValue,sum/float64(k))
}
return maxValue
}
func MaxFloat(a,b float64)float64{
if a>b{
return a
}
return b
}
- code 1423
- code 1838
func maxFrequency(nums []int, k int) int {
sort.Ints(nums)
ans := 1
for l, r, total := 0, 1, 0; r < len(nums); r++ {
total += (nums[r] - nums[r-1]) * (r - l)
for total > k {
total -= nums[r] - nums[l]
l++
}
ans = max(ans, r-l+1)
}
return ans
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
- code 904
func totalFruit(fruits []int) int {
left:=0
windows:=map[int]int{}
maxValue:=0
for right:=0;right<len(fruits);right++{
windows[fruits[right]]++
for len(windows)>2{
windows[fruits[left]]--
if windows[fruits[left]]==0{
delete(windows,fruits[left])
}
left++
}
maxValue=max(maxValue,right-left+1)
}
return maxValue
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
- code 424
func characterReplacement(s string, k int) int {
maxLen:=0
windows:=map[byte]int{}
left:=0
for right:=0;right<len(s);right++{
windows[s[right]]++
if !checkCharacter(windows,k){
windows[s[left]]--
left++
}
maxLen=Max(maxLen,right-left+1)
}
return maxLen
}
func checkCharacter(windows map[byte]int, k int)bool{
sum:=0
max:=0
for _,v:=range windows{
sum=sum+v
max=Max(max,v)
}
return sum-max<=k
}
func Max(a,b int)int{
if a>b{
return a
}
return b
}
- code 1052
func maxSatisfied(customers []int, grumpy []int, minutes int) int {
res:=0
for i:=0;i<len(customers);i++{
if grumpy[i]==0{
res+=customers[i]
customers[i]=0
}
}
left:=0
cur:=0
maxLen:=0
for right:=0;right<len(customers);right++{
cur=cur+customers[right]
if (right-left+1)>minutes{
cur=cur-customers[left]
left++
}
maxLen=max(maxLen,cur)
}
return res+maxLen
}
- code 1610
func visiblePoints(points [][]int, angle int, location []int) int {
sameCnt := 0
polarDegrees := []float64{}
for _, p := range points {
if p[0] == location[0] && p[1] == location[1] {
sameCnt++
} else {
polarDegrees = append(polarDegrees, math.Atan2(float64(p[1]-location[1]), float64(p[0]-location[0])))
}
}
sort.Float64s(polarDegrees)
n := len(polarDegrees)
for _, deg := range polarDegrees {
polarDegrees = append(polarDegrees, deg+2*math.Pi)
}
maxCnt := 0
degree := float64(angle) * math.Pi / 180
for i, deg := range polarDegrees[:n] {
j := sort.Search(n*2, func(j int) bool { return polarDegrees[j] > deg+degree })
if j-i > maxCnt {
maxCnt = j - i
}
}
return sameCnt + maxCnt
}