Leetcode with Golang 滑动窗口 Part1

滑动窗口的定义:

滑动窗口这一个技巧主要运用于处理数组问题上,一般用于“子串”问题。精髓是,维护一个里面装着元素的“窗口”,在将新元素装进“窗口”的同时,根据题意,把不符合题意的元素踢出“窗口”。

滑动窗口的模板:

right:=0
left:=0
for right<len(数组或字符串){
  n = 数组[right]
  right+=1
  for (窗口需要收缩的时候,判断){
    l = 数组[left]
    ...
    left+=1
  }
}

接下来看几道题目:

Leetcode 209.长度最小的子数组

https://leetcode.cn/problems/minimum-size-subarray-sum/

题目简介:找到长度最短的一个子数组。并且数组内数字的和>=target

553c3858f0e045c1a745eaba477f25f6.png

题目分析:窗口不断扩大,当窗口里的元素的总和满足条件后(>=target),窗口缩小,即target减去窗口左端的数。然后再用一个变量记录窗口的大小,最小值随时更新。直接用模板就好了:

func min(i, j int) int {
    if i >= j {
        return j
    } else {
        return i
    }
}
func minSubArrayLen(target int, nums []int) int {
    sum := 0
    right := 0
    left := 0
    res := 10000000
    for right < len(nums) {
        n := nums[right]
        right += 1
        sum += n
        for sum >= target {
            sum -= nums[left]
            res = min(res, right-left)
            left += 1
        }
    }
    if res == 10000000 {
        return 0
    }
    return res
}

 

Leetcode 3.无重复的最长字串

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

 

https://leetcode.cn/problems/longest-substring-without-repeating-characters/description/

f7662d5120b04c4aae730c9c99edae51.png

func lengthOfLongestSubstring(s string) int {
    right := 0
    left := 0
    res := 0
    check_dict := make(map[string]int)
    for right < len(s) {
        word := string(s[right])
        if _, exist := check_dict[word]; !exist {
            check_dict[word] = 1
        } else {
            check_dict[word] += 1
        }
        right += 1
        for check_dict[word] > 1 {
            l := string(s[left])
            left += 1
            check_dict[l] -= 1
        }
        if right-left > res {
            res = right - left
        }

    }
    return res

}

LEETCODE 904.水果成篮

https://leetcode.cn/problems/fruit-into-baskets/description/

题目有点拗口,简单解释:“窗口内”只能含有两种数字。问窗口最长能有多长?

可以用一个字典来装元素。当字典中出现3种及以上数字时,开始收缩窗口。有一个要点,当元素的个数为“0”时,记得把键值对删除。

a9d9f12f0d5a4fa3bb5d89d5bea6f3a5.png

func totalFruit(fruits []int) int {
    right := 0
    left := 0
    res := 0
    dict := make(map[int]int)
    for right < len(fruits) {
       n := fruits[right]
        right+=1
       if _, exist := dict[n]; !exist {
          dict[n] = 1
       } else {
          dict[n] += 1
       }
       for len(dict) > 2 {
          l := fruits[left]
          left += 1
          dict[l] -= 1
          if dict[l] == 0 {
                delete(dict,l)
          }
       }
        if right-left >res{
            res = right-left
        }
    }
    return res
}

 

 

相关推荐

  1. 最大连续1 的个数Ⅲ(滑动窗口)

    2024-01-18 17:44:03       7 阅读
  2. 滑动窗口(单调队列)

    2024-01-18 17:44:03       44 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-18 17:44:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-18 17:44:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-18 17:44:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-18 17:44:03       20 阅读

热门阅读

  1. C++ 提高编程篇2:STL初识

    2024-01-18 17:44:03       30 阅读
  2. HTML 入门级知识点总结

    2024-01-18 17:44:03       28 阅读
  3. 达梦报错:无效IP,设置达梦访问IP白名单

    2024-01-18 17:44:03       34 阅读
  4. 程序员的能力-如何成为不会过时的“码农”

    2024-01-18 17:44:03       30 阅读
  5. 【Flutter】dart构造函数、工厂构造函数

    2024-01-18 17:44:03       33 阅读
  6. 编程笔记 html5&css&js 038 CSS背景

    2024-01-18 17:44:03       35 阅读
  7. localhost与127.0.0.1有啥区别---一篇带你了解清楚

    2024-01-18 17:44:03       33 阅读
  8. MySQL 定时器

    2024-01-18 17:44:03       31 阅读
  9. leetcode 914. 卡牌分组

    2024-01-18 17:44:03       32 阅读