文章目录

  • 前言
  • 开撸
    • 1.lc209 长度最小的数组
    • 2.lc643 子数组最大平均数I
    • 3.lc3 无重复字符的最长子串
    • 4.1695. 删除子数组的最大得分
    • 5. lc76 最小覆盖字串

前言

滑动窗口,可以称为固定间距的双指针(快慢指针+固定步长)
由于它自己独特的性质,所以专门拿出来探讨(双指针指路)

应用场景:数组,字符串

先上东哥(https://labuladong.gitee.io/algo/)的模板(对于模板,可能会限制你的思维,但有时在你突然没有思路的时候有很有帮助)

/* 滑动窗口算法框架 */
void slidingWindow(string s) {HashMap<Character, Integer> window; // hashmap一般用来判断窗口内的字符是否有重复int left = 0, right = 0;while (right < s.length()) {// c 是将移入窗口的字符char c = s.charAt(right);// 增大窗口right++;// 进行窗口内数据的一系列更新.../*** debug 输出的位置 ***/// 在最终的解法代码中不要输出,因为 IO 操作很耗时,可能导致超时System.out.println("window:"+"["+left+","+right+"]"); /********************/// 判断左侧窗口是否要收缩while (window needs shrink) {// d 是将移出窗口的字符char d = s.charAt(left);// 缩小窗口left++;// 进行窗口内数据的一系列更新...}}
}

开撸

1.lc209 长度最小的数组

在数组篇已经介绍过,链接

2.lc643 子数组最大平均数I

lc643 链接

描述:

给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。
请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数

示例:

输入:nums = [1,12,-5,-6,50,3], k = 4
输出:12.75

Solution:
窗口大小固定,直接模拟即可(不需要模板)

public double findMaxAverage(int[] nums, int k) {int sum = 0;for(int i=0;i<k;i++){sum += nums[i];}int resSum = sum;for(int i=0,j=i+k ; j < nums.length ; i++,j++){sum -= nums[i];sum += nums[j];resSum = sum>resSum?sum:resSum;}return (double)resSum/k;}

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

lc3 链接

描述:

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

示例:

输入: s = “abcabcbb”
输出: 3

Solution:
(也是滑动窗口,看到重复要想到哈希表啊!)

public int lengthOfLongestSubstring1(String s) {HashSet<Character> hashset = new HashSet<>();int resLen = 0; // 设置初始最长字符串长度为0// 设置左右指针for(int left=0,right=0;right<s.length();left++){// 如果不重复,就添加到哈希表中while(right<s.length() && !hashset.contains(s.charAt(right))  ){hashset.add(s.charAt(right));right++;}// 循环结束,就代表遇到了重复的,所以移除最开始的字母hashset.remove(s.charAt(left));// 记录此时的长度(此时right已经指向下一重复字符,所以长度直接r-l)resLen = Math.max((right-left),resLen);}return resLen;}

4.1695. 删除子数组的最大得分

lc1695 链接

描述:

题目有点复杂,简单点说,给你一个正整数数组 nums ,求累加和最大的无重复元素的连续子数组,返回其累加和的值

示例:

输入:nums = [4,2,4,5,6]
输出:17

Solution:
(和lc3几乎一样,就多一个求和)

public int maximumUniqueSubarray(int[] nums) {HashSet<Integer> hashset = new HashSet<>();int resSum=0; // 记录最终的和int sum = 0;  // 记录临时(每一次)的和int len = nums.length;for(int i=0,j=0;j<len;i++){// 第一次循环不用剔除最开始的数if(i!=0)sum -= nums[i-1];while( j<len && !hashset.contains(nums[j]) ){hashset.add(nums[j]);sum+=nums[j++];}resSum = Math.max(sum, resSum);hashset.remove(nums[i]);}return resSum;}

5. lc76 最小覆盖字串

lc76 链接

描述:

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “”

示例:

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

Solution:

 public static  String minWindow(String s, String t) {//1.维护两个map记录窗口中的符合条件的字符以及need的字符Map<Character,Integer> window = new HashMap<>();Map<Character,Integer> need = new HashMap<>();// 先将字符串t中的字符存入need哈希表中for(int i=0;i<t.length();i++){char ch = t.charAt(i);need.put(ch,need.getOrDefault(ch,0)+1);}int left = 0,right = 0; // 左右双指针//count记录当前窗口中符合need要求的字符的数量,当count == need.size()时即可shrik窗口int count = 0; int start = 0; //start表示符合最优解的substring的起始位序int len = Integer.MAX_VALUE; //len用来记录最终窗口的长度,并且以len作比较//一次遍历找“可行解”while(right < s.length()){//更新窗口char c = s.charAt(right);right++; //窗口扩大if(need.containsKey(c)){window.put(c,window.getOrDefault(c,0)+1);// 当前窗口拥有的字符及对应的数量和need一样时,count就加1if(need.get(c).equals(window.get(c))){count++;}}//收缩窗口,找符合条件的最优解while(count == need.size()){// 找到最短len,并记录此时的开始索引startif(right - left < len){len = right - left;start = left;}//更新窗口——这段代码逻辑几乎完全同上面的更新窗口char d = s.charAt(left);left++; //左指针右移,窗口缩小if(need.containsKey(d)){// 注意这里和上面的顺序if(need.get(d).equals(window.get(d))){count--;}window.put(d,window.get(d)-1);}}}return len == Integer.MAX_VALUE ? "" : s.substring(start,start+len);}

参考链接:
https://leetcode.cn/problems/longest-substring-without-repeating-characters/solution/yi-ge-mo-ban-miao-sha-10dao-zhong-deng-n-sb0x/

LeetCode算法思想之滑动窗口相关推荐

  1. LeetCode刷题:滑动窗口模板以及典型例题

    作者:fuxuemingzhu 链接:https://leetcode-cn.com/problems/max-consecutive-ones-iii/solution/fen-xiang-hua- ...

  2. 算法与数据结构 - 滑动窗口

    滑动窗口 滑动窗口的作用是可以将一部分问题中的嵌套循环转变为一个单循环,因此可以减少时间复杂度. 滑动窗口的基本思想 使用 left 和 right 指针来指定窗口大小,默认值都为 0. 先让 rig ...

  3. 面试难点!常用算法技巧之“滑动窗口”

    算法简介 滑动窗口,顾名思义,就是有一个大小可变的窗口,左右两端方向一致的向前滑动(右端固定,左端滑动:左端固定,右端滑动). 可以想象成队列,一端在push元素,另一端在pop元素,如下所示: 假设 ...

  4. 【算法3】---滑动窗口(python)

    目录 算法3 --- 滑动窗口(python) :mega: `前言:` :sun_with_face: `基本思想:` :closed_book: `代码示例:` :triangular_flag_ ...

  5. LeetCode Contains Duplicate III(滑动窗口)

    问题:给出一个数组,要求  思路:第一种方法使用枚举法,对于i,则判断[0,i-k]之间的数与nums[i]的绝对值是否小于等于t. 第二种方法基于set的滑动窗口.在遍历数组时,先看集合中比当前遍历 ...

  6. 算法篇之-----滑动窗口(尺取法)

    滑动窗口(尺取法 1. 介绍 2. 滑动窗口法的大体框架 4.最小覆盖子串 5.窗口数量 6.最小值 1. 介绍 滑动窗口法,也叫尺取法(可能也不一定相等,大概就是这样 =.=),可以用来解决一些查找 ...

  7. LeetCode 76. 最小覆盖子串 (滑动窗口哈希表)

    LeetCode 76. 最小覆盖子串 思路: 准备一个map1记录字符串t(字符, 字符个数) 准备一个map2记录在s的窗口中所包含的t串字符(字符,字符个数) 左端点收缩条件:窗口内已经覆盖了t ...

  8. 【Leetcode数组--子数组--滑动窗口】209. 长度最小的子数组 904. 水果成篮 1004. 最大连续1的个数 III 76. 最小覆盖子串(有数组操作中重要的方法:滑动窗口!!!!)

    文章目录 Leetcode209 1.问题描述 2.解决方案 解法一:两个错误思路的算法 解法二:暴力 解法三:滑动窗口法(O(n)) Leetcode904 1.问题描述 2.解决方案 Leetco ...

  9. 算法小模板|滑动窗口(模拟)

    滑动窗口(模拟) double findMaxAverage(int* nums, int numsSize, int k) {int sum = 0;for(int i=0;i<k;i++){ ...

最新文章

  1. 深入剖析Kubernetes k8s
  2. JavaScript 编程精解 中文第三版 零、前言
  3. 实训09.08:简单的算法练习
  4. hdu1024Max Sum Plus Plus
  5. Google Guava缓存实现接口的限流
  6. yarn 卸载包_0609-6.1.0-如何卸载CDH6.1
  7. 解决WIN7有限的访问权限的终极解决方案合集
  8. 去过印度的人评价印度_印度的学生如何开始使用开源
  9. element table批量删除_element ui 批量删除
  10. 牛客网刷题知识汇总2
  11. [转贴]人老总是一场空
  12. MySQL初始化安装部署
  13. codevs 1017 乘积最大
  14. canvas与svg的区别
  15. 通俗易懂的极限学习机(Extreme Learning Machine)
  16. 编写一个油猴脚本,去除百度首页的广告卡片(亲测有效)
  17. JAVA中的getBytes()方法(史上最能明白的总结)
  18. Java 创建一个Customer类,类中的属性有姓名、年龄、性别,然后创建两个Customer对象,把这两个对象存储在ArrayList对象中,然后再从ArrayList对象中读取出来。
  19. 【Unity3D】分离路面导航
  20. 3.字体样式,分隔线与段落

热门文章

  1. 用Seafile搭建私有云盘
  2. 创业公司的各种利器——工具推荐
  3. 网络对抗技术-Exp2-后门原理与实践 20181314
  4. 医疗大数据分析的主流解决方案总结
  5. 设置flashget下载任务完成后自动调用avast!扫描文件
  6. BAPI相关知识整理
  7. 提效小技巧——记录那些不常用的代码片段
  8. 初识C语言:从0开始,由菜鸟变大牛(3)
  9. 作为程序员该了解的8条冷知识
  10. 怎么看主机是否支持4k?