一起学算法(滑动窗口篇)

news2024/9/20 6:40:15

前言:

        对于滑动窗口,有长度固定的窗口,也有长度可变的窗口,一般是基于数组进行求解,对于一个数组中两个相邻的窗口,势必会有一大部分重叠,这部分重叠的内容是不需要重复计算的,所以我们可以通过相邻的窗口进行数据的延伸使用

1.固定窗口

1.定义

       如上图所示,两个相邻的长度为4的窗口(图中红色部分),下一个窗口一定比前一个窗口少一个数据,或者是多一个数据

       橘色为切换窗口时少的那个数据,黄色为切换窗口时多出来的那个数据,所以,可以直接沿用之前的数据,并且减去橙色的数据,加上黄色的数据,就是我们下一个窗口的值了,这就是滑动窗口的一个经典思路

2.例题解析:

给定一个数组num和两个整数k和target,请你返回长度为k且和大于target的子数组数目

    public int partitionString(int[] num,int k,int target) {
      if(num==null||num.length==0){
          return 0;
      }
      int sum=0;
      int i=0;
      for(;i<k;i++){
          sum+=num[i];
      }
      int count=0;
      if(sum>=target){
          count++;
      }
      for(int left=0;left<num.length;left++){
          sum-=num[left];
          sum+=num[++i];
          if(sum>=target){
              count++;
          }
      }
      return count;
    }
  • 首先统计前k个数的sum,作为窗口的初始值,并且判断该子数组是否符合条件,符合则个数+1,不符合不用做操作
  • 因为窗口时固定的,所以窗口左右端点同时向右移动,再次判断窗口中的数组是否满足条件,以O(1)的方式判断条件是否满足
  • 最后返回计数器的值

2.可变窗口

可变窗口一般是使用双指针实现的,下面提供可变窗口的一个模板:

/* 滑动窗口算法框架 */
void slidingWindow(String s) {
    // 用合适的数据结构记录窗口中的数据
    HashMap<Character, Integer> window = new HashMap<>();
    //用合适的数据结构记录需要的数据

    int left = 0, right = 0;
    while (right < s.length()) {
        // c 是将移入窗口的字符
        char c = s.charAt(right);
        window.put(c, window.getOrDefault(c, 0) + 1);
        // 增大窗口
        right++;
        // 进行窗口内数据的一系列更新
        ...

        // 判断左侧窗口是否要收缩  计算窗口中特殊个数时,可能以个数为条件
        while (left < right && window needs shrink) {
            // d 是将移出窗口的字符
            char d = s.charAt(left);
            window.put(d, window.get(d) - 1);
            // 缩小窗口
            left++;
            // 进行窗口内数据的一系列更新
            ...
        }
    }
}

leetcode题单:

删除元素后全为1的子数组

   public int longestSubarray(int[] nums) {
    int flag=0;
    int left=0;
    int mid=0;
    int max=0;
    for(int right=0;right<nums.length;right++) {
        if (nums[right] != 1) {
            flag++;
            if (flag > 1) {
                left = mid + 1;
                flag--;
            }
            mid = right;
        }
        max=Math.max(max,right-left);
    }
    return max;
    }

最大的连续1的个数

    public int longestOnes(int[] nums, int k) {
        if(nums==null||nums.length==0){
            return 0;
        }
        int left=0;
        int ans=0;
        int count=0;
        for (int right = 0; right <nums.length; right++) {
            //如果是为0的话,数值加1,为1的话,不用进行运算
            count+=1-nums[right];
            while(count>k){
                count-=1-nums[left++];
            }
            ans=Math.max(ans,right-left+1);
        }
        return ans;
    }

找到最长的半重复子字符串

public int longestSemiRepetitiveSubstring(String s) {
    char[] str = s.toCharArray();  // 将字符串转换为字符数组
    int left = 0;  // 左指针初始位置
    int same = 0;  // 记录当前连续相同字符的个数
    int max = 1;  // 记录最长的半重复子串长度
    
    for (int right = 1; right < str.length; right++) {
        if (str[right] == str[right - 1] && ++same > 1) {  // 发现连续相同字符序列
            left++;  // 将左指针向右移动一位
            while (left < right && same > 1) {
                if (str[left] == str[left - 1]) {  // 当前字符与前一个字符相同
                    same--;  // 重置连续相同字符的个数
                    continue;
                }
                left++;  // 将左指针向右移动一位
            }
        }
        max = Math.max(max, right - left + 1);  // 更新最长的半重复子串长度
    }
    
    return max;  // 返回最长的半重复子串长度
}

最小覆盖子串(不固定窗口)

   public String minWindow(String s, String t) {
        //利用滑动茶窗口进行求解
        //记录需要的字符
        Map<Character,Integer> need=new HashMap<>();
        //记录窗口中所用的字符
        Map<Character,Integer>windows=new HashMap<>();
        for(char c:t.toCharArray()){
            need.put(c,need.getOrDefault(c,0)+1);
        }
        //作指针
        int left=0;
        //右指针
        int right=0;
        //窗口中满足需要字符的个数
        int vaild=0;
        int start=0;
        int len=Integer.MAX_VALUE;
        while(right<s.length()){
            //往窗口移进的字符
            char c=s.charAt(right);
            right++;
            if(need.containsKey(c)){
                windows.put(c,windows.getOrDefault(c,0)+1);
                if(windows.get(c).equals(need.get(c))){
                    vaild++;
                }
                //判断左侧窗口是否收缩
                while(vaild==need.size()){
                    //更新最小的覆盖子串
                    if(right-left<len){
                        start=left;
                        len=right-left;
                    }
                    //d是移出窗口的字符
                    char d=s.charAt(left);
                    left++;
                    if(need.containsKey(d)){
                        if(windows.get(d).equals(need.get(d))){
                            vaild--;
                        }
                        windows.put(d,windows.get(d)-1);
                    }
                }
            }

        }
        return len==Integer.MAX_VALUE?"":s.substring(start,start+len);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/835720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos适配人大金仓国产数据库

nacos版本2.2.0 人大金仓版本8.6.0 一、相关文件 Nacos官方文档-数据源插件https://nacos.io/zh-cn/docs/v2/plugin/datasource-plugin.html Nacos2.2.0源码https://github.com/alibaba/nacos/archive/refs/tags/2.2.0.zip 人大金仓驱动https://download.csdn.net/download/q…

无人机航测技术有何特点?主要应用在哪些方面?

无人机航测是航空摄影测量的一种&#xff0c;主要面向低空遥感领域&#xff0c;具有成本低、快速高效、适用范围广等特点。目前&#xff0c;无人机航测主要应用于地形测绘、城市数字化建设、工程建设等方面。 无人机航测技术的特点 1、作业成本低 传统的人工测量技术主要利用…

Bigemap如何查看高清影像图

工具 Bigemap gis office地图软件 分享一个可以查看非常高清影像图的软件&#xff0c;平时外出徒步的时候用来查看路线。 首先要去搜索安装bigemap gis office这个软件&#xff0c;打开软件&#xff0c;要提示你去添加地图的。然后去点击选择地图这个按钮&#xff0c;列表中有…

CobaltStirke BOF技术剖析(一)|BOF实现源码级分析

简介 对BOF(Beacon Object File)的支持是在CobaltStrike4.1版本中新引入的功能。BOF文件是由c代码编译而来的可在Beacon进程中动态加载执行的二进制程序。无文件执行与无新进程创建的特性更加符合OPSEC的原则&#xff0c;适用于严苛的终端对抗场景。低开发门槛与便利的内部Bea…

Linux学习之延时计划任务anacontab和锁文件flock

cat /etc/redhat-release看到操作系统的版本是CentOS Linux release 7.6.1810 (Core)&#xff0c;uname -r可以看到内核版本是3.10.0-957.21.3.el7.x86_64 参考的博客有&#xff1a; 1.《Linux anacron命令用法详解》 2.《详解anacron 命令》 3.《Anacron的用法》 4.《shell脚…

ip网络广播系统网络音频解码终端公共广播SV-7101

SV-7101V网络音频终端产品简介 网络广播终端SV-7101V&#xff0c;接收网络音频流&#xff0c;实时解码播放。本设备只有网络广播功能&#xff0c;是一款简单的网络广播终端。提供一路线路输出接功放或有源音箱。 产品特点 ■ 提供固件网络远程升级■ 标准RJ45网络接口&…

Android:自己写一个简单记事本

一、前言&#xff1a;我的app是点击加号跳转到另一个界面 那么我遇到的问题的是点击加号是一个从一个Fragment跳转到另一个Fragment跳转失败。 二、解决方案&#xff1a; //相应控件的监听里面实现跳转FragmentManager fragmentManagergetFragmentManager();fragmentManager.b…

51单片机学习-AT24C02数据存储秒表(定时器扫描按键数码管)

首先编写I2C模块&#xff0c;根据下面的原理图进行位声明&#xff1a; sbit I2C_SCL P2^1; sbit I2C_SDA P2^0;再根据下面的时序结构图编写函数&#xff1a; /*** brief I2C开始* param 无* retval 无*/ void I2C_Start(void) {I2C_SDA 1; I2C_SCL 1; I2C_SDA 0;I2C_S…

HTML+CSS+JavaScript:利用事件委托实现tab栏切换

一、需求 实现tab栏切换 二、代码素材 以下是缺失JS部分的代码&#xff0c;感兴趣的小伙伴可以先自己试着写一写 <!-- JS方法实现tab栏切换 --> <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta …

[java刷算法]牛客—剑指offer链表复习、手写简易正则匹配

&#x1f9db;‍♂️个人主页&#xff1a;杯咖啡&#x1f4a1;进步是今天的活动&#xff0c;明天的保证&#xff01;✨目前正在学习&#xff1a;SSM框架,算法刷题&#x1f449;本文收录专栏 &#xff1a; java刷算法牛客—剑指offer&#x1f64c;牛客网&#xff0c;刷算法过面试…

【传统视觉】C#创建、封装、调用类库

任务 因为实现代码相对简单&#xff0c;然后又没有使用Opencv&#xff0c;所以就直接用C#实现&#xff0c;C#调用。 1.创建类库 1.1新建一个类库 vs2015 > 文件 > 新建 > 项目 using System; using System.Collections.Generic; using System.Linq;namespace Yo…

使用ChatGPT编写技术文档

技术文档对于任何项目都是至关重要的&#xff0c;因为它确保所有利益相关者都在同一层面上&#xff0c;并允许有效的沟通和协作。创建详细而准确的技术文档可能既耗时又具有挑战性&#xff0c;特别是对于那些不熟悉主题或缺乏强大写作技巧的人来说。ChatGPT 是一个强大的人工智…

服务器流量

1.服务器流量分为入流量和出流量 入流量&#xff08;Inbound Traffic&#xff09;是指流向服务器的数据流量&#xff0c;也就是客户端发送到服务器的数据。这些数据可能包括请求信息、文件上传等。 出流量&#xff08;Outbound Traffic&#xff09;是指从服务器流向客户端的数…

[C++] 类与对象(中)类中六个默认成员函数(2)-- 运算符重载 -- 取地址及const取地址操作符重载

1、前言 本篇我们以日期类来展开讲。对于一个日期&#xff0c;我们如何去比大小呢&#xff1f;对年月日依次进行比较可以&#xff0c;但是可以直接比较吗? 我们可以看到&#xff0c;对于自定义类型的日期类直接去比较两个日期的大小是错误的&#xff0c;因此我们需要对运算符赋…

C. Candy Store

Problem - 1798C - Codeforces 思路&#xff1a;要求的最小的标签数量&#xff0c;我们可以先考虑贪心&#xff0c;对于第一个来说它一定会使用一个标签&#xff0c;然后就让后面尽可能多的跟当前这个共用一个标签&#xff0c;如果不行&#xff0c;则在使用一个新的。那么对于共…

Python+Robot Framework实现接口自动化测试

最近在研究PythonRobot Framework的接口自动化&#xff0c;摸清了一些套路&#xff0c;想着总结一下&#xff0c;分享给大家&#xff0c;希望对做自动化的同学有所启发。 主要用到了Python的requests&#xff0c;json&#xff0c;hashlib库&#xff0c;下面以登录和开启文档/目…

“云教室”来了! 麒麟信安打造晋城市红星小学多媒体教室建设新标杆

当前&#xff0c;教育行业正面临教育信息化的重大变革。随着信息技术的发展&#xff0c;集声音、图像、视频动画等多种功能于一体的信息技术课逐渐成为学生群体最受欢迎的课程之一。 近日&#xff0c;麒麟信安为晋城市红星小学量身打造的“云教室”全新上线。据悉&#xff0c;…

IDEA如何生成 serialVersionUID

序列化和反序列化 Java是面向对象的语言&#xff0c;与其他语言进行交互&#xff08;比如与前端js进行http通信&#xff09;&#xff0c;需要把对象转化成一种通用的格式比如json&#xff08;前端显然不认识Java对象&#xff09;&#xff0c;从对象到json字符串的转换&#xff…

【css】css实现字母大小写转换

text-transform 属性用于指定文本中的大写和小写字母。 uppercase&#xff1a;将字母转为大写lowercase&#xff1a;将字母转为小写capitalize&#xff1a;将每个单词首字母转为大写 代码&#xff1a; <style> p.uppercase {text-transform: uppercase; }p.lowercase …

Mendix Excel导出介绍

一、前言 之前我们聊到企业实现应用现代化是一项长期的任重道远的工作&#xff0c;通过Excel导入组件可以作为一个好的起点把企业的业务从线下迁移到线上&#xff0c;当把应用迁移之后&#xff0c;最终结果会有各种的报表展示&#xff0c;这时基于实际业务的需求&#xff0c;我…