leetcode滑动窗口问题

想成功先发疯,不顾一切向前冲。

第一种

定长滑动窗口

. - 力扣(LeetCode)1456.定长子串中的元音的最大数目. - 力扣(LeetCode)

No.1

定长滑窗套路
我总结成三步:入-更新-出。

        1. 入:下标为 i 的元素进入窗口,更新相关统计量。如果 i<k−1 则重复第一步。
        2. 更新:更新答案。一般是更新最大值/最小值。        
        3. 出:下标为 i−k+1 的元素离开窗口,更新相关统计量。
以上三步适用于所有定长滑窗题目。

class Solution {public int maxVowels(String S, int k) {char[] s = S.toCharArray();int ans = 0;int temp = 0;for (int i = 0; i < s.length; i++) {// 1. 进入窗口if (s[i] == 'a' || s[i] == 'e' || s[i] == 'i' || s[i] == 'o' || s[i] == 'u') {temp++;}if (i < k - 1) { // 窗口大小不足 kcontinue;}// 2. 更新答案ans = Math.max(ans, temp);// 3. 离开窗口char out = s[i - k + 1];if (out == 'a' || out == 'e' || out == 'i' || out == 'o' || out == 'u') {temp--;}}return ans;}
}
复杂度分析
  • 时间复杂度:O(n),其中 n 是 s 的长度。
  • 空间复杂度:O(1)。仅用到若干额外变量。

这里对于字符串的处理及java的String类做一个详细说明

toCharArray()

是 Java 中 String 类的一个方法,用于将字符串转换为字符数组 (char[])。每个字符数组中的元素对应于字符串中的一个字符。

用法

String str = "Hello, World!"; char[] charArray = str.toCharArray();

解释

  • str 是一个 String 对象。
  • 调用 str.toCharArray() 会将字符串 "Hello, World!" 转换为一个字符数组。
  • charArray 将包含:{'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!'}

常见用途

  • 字符串处理:你可以更方便地遍历字符串中的每个字符。
  • 字符修改:字符数组可以修改单个字符,而 String 是不可变的(即一旦创建,不能更改其内容)。

    1. length()

  • 作用: 返回字符串的长度(字符数)。
    • 示例:
      String str = "Hello, World!"; 
      int len = str.length(); // len = 13 
  • 2. charAt(int index)

  • 作用: 返回指定索引处的字符,索引从 0 开始。
  • 示例:
    String str = "Hello"; 
    char ch = str.charAt(1); // ch = 'e'

  • 3. substring(int beginIndex) / substring(int beginIndex, int endIndex)

  • 作用: 返回从指定索引开始或在索引区间内的子字符串。
  • 示例:
    String str = "Hello, World!"; 
    String subStr1 = str.substring(7); // subStr1 = "World!" 
    String subStr2 = str.substring(0, 5); // subStr2 = "Hello" 

  • 4. indexOf(String str) / indexOf(char ch)

  • 作用: 返回指定字符或子字符串在原字符串中第一次出现的索引,若未找到则返回 -1。
  • 示例:
    String str = "Hello, World!"; 
    int index1 = str.indexOf('W'); // index1 = 7 
    int index2 = str.indexOf("World"); // index2 = 7 

  • 5. toUpperCase() / toLowerCase()

  • 作用: 返回将字符串转换为大写或小写后的新字符串。
  • 示例:
    String str = "Hello"; 
    String upperStr = str.toUpperCase(); // upperStr = "HELLO" 
    String lowerStr = str.toLowerCase(); // lowerStr = "hello" 

  • 6. trim()

  • 作用: 去除字符串开头和结尾的空白字符。
  • 示例:
    String str = " Hello, World! "; 
    String trimmedStr = str.trim(); // trimmedStr = "Hello, World!" 

  • 7. replace(char oldChar, char newChar) / replace(CharSequence target, CharSequence replacement)

  • 作用: 替换字符串中的指定字符或子字符串。
  • 示例:
    String str = "Hello, World!"; 
    String replacedStr1 = str.replace('o', 'a'); // replacedStr1 = "Hella, Warld!" 
    String replacedStr2 = str.replace("World", "Java"); // replacedStr2 = "Hello, Java!" 

  • 8. equals(Object anObject) / equalsIgnoreCase(String anotherString)

  • 作用: 比较两个字符串的内容是否相等。equalsIgnoreCase 不区分大小写
  • 示例:
    String str1 = "Hello"; 
    String str2 = "hello"; 
    boolean isEqual = str1.equals(str2); // isEqual = false 
    boolean isEqualIgnoreCase = str1.equalsIgnoreCase(str2); // isEqualIgnoreCase = true

  • 9. split(String regex)

  • 作用: 根据正则表达式将字符串分割为子字符串数组。
  • 示例:
    String str = "apple,banana,orange"; 
    String[] fruits = str.split(","); // fruits = ["apple", "banana", "orange"] 

  • 10. contains(CharSequence s)

  • 作用: 判断字符串是否包含指定的字符序列。
  • 示例:
    String str = "Hello, World!"; 
    boolean containsHello = str.contains("Hello"); // containsHello = true

No.2

给你一个 下标从 0 开始 的整数数组 nums ,其中 nums[i] 表示第 i 名学生的分数。另给你一个整数 k 。

从数组中选出任意 k 名学生的分数,使这 k 个分数间 最高分 和 最低分 的 差值 达到 最小化 。

返回可能的 最小差值 。

示例 1:

输入:nums = [90], k = 1
输出:0
解释:选出 1 名学生的分数,仅有 1 种方法:
- [90] 最高分和最低分之间的差值是 90 - 90 = 0
可能的最小差值是 0

示例 2:

输入:nums = [9,4,1,7], k = 2
输出:2
解释:选出 2 名学生的分数,有 6 种方法:
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 4 = 5
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 1 = 8
- [9,4,1,7] 最高分和最低分之间的差值是 9 - 7 = 2
- [9,4,1,7] 最高分和最低分之间的差值是 4 - 1 = 3
- [9,4,1,7] 最高分和最低分之间的差值是 7 - 4 = 3
- [9,4,1,7] 最高分和最低分之间的差值是 7 - 1 = 6
可能的最小差值是 2
class Solution {public int minimumDifference(int[] nums, int k) {Arrays.sort(nums);int len = nums.length;int res = Integer.MAX_VALUE;for (int i = 0; i <= len - k; i++) {res = Math.min(res,nums[i+k-1]-nums[i]);}return res;}
}

这个题要注意的地方是:i  只有在 <= len-k 的条件下可以运行,在后续的nums[ ]读数的时候左右节点要进行移动读数;

No.3

1343. - 力扣(LeetCode)

class Solution {public int numOfSubarrays(int[] arr, int k, int threshold) {int len = arr.length;int ans = 0;for (int i = 0; i < k; i++) {ans += arr[i];}int res = 0;
//很典型的一个坑,初次忘记考虑当 i = 0 取 k 个数的时候的 ans 的大小的判断if(ans>=k*threshold){res++;}for (int i = k; i < len; i++) {ans = ans-arr[i-k] +arr[i];if(ans/k>=threshold){res++;}}return res;}
}

不定长滑动窗口(求最长或最大)

No.1

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

我认为思考的重点在于滑动窗口的起始位置与一般规律的总结:

我们不妨以示例一中的字符串 abcabcbb 为例,找出从每一个字符开始的,不包含重复字符的最长子串,那么其中最长的那个字符串即为答案。对于示例一中的字符串,我们列举出这些结果,其中括号中表示选中的字符以及最长的字符串:

以 (a)bcabcbb 开始的最长字符串为 (abc)abcbb;
以 a(b)cabcbb 开始的最长字符串为 a(bca)bcbb;
以 ab(c)abcbb 开始的最长字符串为 ab(cab)cbb;
以 abc(a)bcbb 开始的最长字符串为 abc(abc)bb;
以 abca(b)cbb 开始的最长字符串为 abca(bc)bb;
以 abcab(c)bb 开始的最长字符串为 abcab(cb)b;
以 abcabc(b)b 开始的最长字符串为 abcabc(b)b;
以 abcabcb(b) 开始的最长字符串为 abcabcb(b)。

class Solution {public int lengthOfLongestSubstring(String S) {int len = S.length();char[] s = S.toCharArray();Set<Character> hs = new HashSet<>();int res = 0;for (int left = 0, right = 0; right < len; right++) {char ch = s[right];while (hs.contains(ch)) {hs.remove(s[left]);left++;}hs.add(s[right]);res = Math.max(res, right - left + 1);}return res;}
}
  • right: 当前子串的右边界索引。
  • left: 当前子串的左边界索引。

子串的长度计算公式是 右边界索引 - 左边界索引 + 1寓意着包含左右边界的字符串

No.2

1695.删除子数组的最大得分. - 力扣(LeetCode)

给你一个正整数数组 nums ,请你从中删除一个含有 若干不同元素 的子数组删除子数组的 分 就是子数组各元素之 和 。

返回 只删除一个 子数组可获得的 最大得分 。

如果数组 b 是数组 a 的一个连续子序列,即如果它等于 a[l],a[l+1],...,a[r] ,那么它就是 a 的一个子数组。

示例 1:

输入:nums = [4,2,4,5,6]
输出:17
解释:最优子数组是 [2,4,5,6]

示例 2:

输入:nums = [5,2,1,2,5,2,1,2,5]
输出:8
解释:最优子数组是 [5,2,1] 或 [1,2,5]
class Solution {public int maximumUniqueSubarray(int[] nums) {int len = nums.length; // 获取数组的长度Set<Integer> hs = new HashSet<>(); // 创建一个 HashSet 用来存储当前子数组的元素int res = 0, ans = 0; // res 用于存储当前子数组的元素和,ans 用于存储最大得分int i = 0; // i 指针,表示当前子数组的起点// j 指针表示当前子数组的终点for (int j = 0; j < len; j++) {// 当 hs 中已经包含 nums[j] 时,说明存在重复元素,需要移动 i 指针while (hs.contains(nums[j])) {hs.remove(nums[i]); // 从 HashSet 中移除子数组的第一个元素res -= nums[i]; // 从当前子数组的和中减去该元素的值i++; // 移动起点指针 i}hs.add(nums[j]); // 将 nums[j] 添加到 HashSet 中res += nums[j]; // 将 nums[j] 的值加到当前子数组的和中ans = Math.max(res, ans); // 更新最大得分}return ans; // 返回只删除一个子数组可以获得的最大得分}
}

No.3 上难度

1004.最大连续1的个数III. - 力扣(LeetCode)

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k 个 0 ,则返回 数组中连续 1 的最大个数 。

示例 1:

输入:nums = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释:[1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。

示例 2:

输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。

这个题有个特点就是数组内只有 0 ,1

那我们就围绕这一特点进行攻破,及,cnt += 1 - nums[right];  // 如果 nums[right] 是 0,`cnt` 增加1;如果是 1,`cnt` 不变

class Solution {public int longestOnes(int[] nums, int k) {int cnt = 0;  // 记录当前窗口内0的个数int ans = 0;  // 记录最长的全1子数组的长度int left = 0; // 滑动窗口的左边界// 右边界 `right` 从 0 开始遍历整个数组for (int right = 0; right < nums.length; right++) {cnt += 1 - nums[right]; // 如果 nums[right] 是 0,`cnt` 增加1;如果是 1,`cnt` 不变// 如果当前窗口内的0的个数超过了允许的k个,则需要收缩窗口while (cnt > k) {cnt -= 1 - nums[left]; // 移动左边界,移除 `nums[left]` 的影响left++; // 将左边界右移}// 更新最长子数组的长度ans = Math.max(ans, right - left + 1);}return ans; // 返回找到的最长的全1子数组的长度}
}

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

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

相关文章

docker inspect输出内容详解,推测容器运行命令

原始输出 [{"Id": "c2496d852ee3affd295a177e9f26f163a53da8d11e3708d6a479f189f707ad0b","Created": "2024-08-04T02:43:24.909341103Z","Path": "/startup.sh","Args": [],"State": {&quo…

lambda 表达式可以传递引用为什么需要引用捕获

当 lambda 表达式被传递或存储在其他地方时&#xff0c;通过引用捕获可以确保它始终访问正确的外部变量。—— 引用捕获可以精确地控制被捕获的引用变量的作用域。如果一个 lambda 表达式被存储在一个容器中&#xff0c;并且在不同的时间点被调用&#xff0c;引用捕获可以确保它…

入门STM32—外部中断

外部中断的存在使得微控制器能够及时响应外部事件&#xff0c;避免频繁的轮询操作&#xff0c;从而提高系统的实时性、效率和低功耗性能。 1.什么是外部中断&#xff1f; 外部中断是指微控制器接收到外部引脚的信号变化时触发的中断。STM32F103系列微控制器支持多个外部中断线…

鸿蒙(API 12 Beta3版)【DRM会话管理(C/C++)】数字版权保护开发

DRM会话管理&#xff08;MediaKeySession&#xff09;支持媒体密钥管理及媒体解密等&#xff0c;MediaKeySession实例由系统管理里的MediaKeySystem实例创建和销毁。 开发步骤 导入NDK接口&#xff0c;接口中提供了DRM相关的属性和方法&#xff0c;导入方法如下。 #include &…

学习嵌入式第二十九天

ipc进程间通信方式 PC&#xff0c;即进程间通信&#xff08;Inter-Process Communication&#xff09;&#xff0c;是操作系统中不同进程之间交换数据的一种机制。以下是一些常见的IPC方式&#xff1a; 管道&#xff1a;用于父子进程或兄弟进程之间的通信。消息队列&#xff…

selenium-java实现自动登录跳转页面

如果要一直刷新一个网页&#xff0c;总不能人工一直去点&#xff0c;所以想到大学时候学过selenium技术&#xff0c;写个脚本来一直刷新&#xff0c;因为经常写java语言&#xff0c;所以选用java语言来写 实验环境 注意&#xff0c;需要先准备好Google浏览器和Chrome-Driver驱…

除了系统问题 前端可能会有什么问题

目录 1.问题&#xff1a;页面加载缓慢&#xff0c;用户体验不佳。2.问题&#xff1a;页面在不同设备和屏幕尺寸下显示效果不佳。3.问题&#xff1a;不同浏览器对CSS和JS的支持程度不同&#xff0c;导致页面在不同浏览器下表现不一致。4.问题&#xff1a;页面中的事件处理不当&a…

代码随想录跟练第六天——LeetCode

第454题.四数相加II 力扣题目链接(opens new window) 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。 为了使问题简单化&#xff0c;所有的 A, B, C, D 具有相同的长度 N&#xff0c;且 0 ≤ N ≤…

极限02:两个重要极限

1.夹逼准则 定义&#xff1a;设{ a n a_n an​}, { b n b_n bn​}, { c n c_n cn​}为实数列&#xff0c; a n ≤ b n ≤ c n a_n≤b_n≤c_n an​≤bn​≤cn​, 且 lim ⁡ n → ∞ a n lim ⁡ n → ∞ c n l \lim_{n \to \infty} a_n \lim_{n \to \infty} c_n l n→∞lim​…

ffmpeg6.1集成Plus-OpenGL-Patch滤镜

可参考上一篇文章。ffmpeg6.1集成ffmpeg-gl-transition滤镜-CSDN博客 安装思路大致相同&#xff0c; 因为 Plus-OpenGL-Patch也是基于 ffmpeg 4.x 进行开发的&#xff0c;所以在高版本上安装会有很多报错。 这是我安装后的示例&#xff0c;需要安装教程或者改代码可私信我。 …

记录一次 Redis 优化发送数据(使用管道批量传送)

一 项目背景 此前的项目中&#xff0c;鉴于客户方服务器的安全配置对 MQ 中间件有所限制&#xff0c;我们只得采用 Redis 的 list 作为简易的 MQ 来传送报文数据。然而&#xff0c;近段时间客户关闭了相关端口&#xff0c;导致大量数据积压&#xff0c;需要进行补发。在补发过程…

大数据背景下基于Python的牛油果销售数据可视化分析

注&#xff1a;源码在最后&#xff0c;只是一次实验记录&#xff0c;不合理的地方自行修改。 一 研究背景及意义 21世纪以来&#xff0c;随着科学技术的进步&#xff0c;人们的生活水平也随之大幅提升提高。在科技和经济快速发展下&#xff0c;全球已经进入了大数据时代。大数…

8.21-部署eleme项目

1.设置主从从mysql57服务器 &#xff08;1&#xff09;配置主数据库 [rootmsater_5 ~]# systemctl stop firewalld[rootmsater_5 ~]# setenforce 0[rootmsater_5 ~]# systemctl disable firewalldRemoved symlink /etc/systemd/system/multi-user.target.wants/firewalld.serv…

使用 Fyne 构建 GUI 应用:设置标签文本和自增计数器

引言 Fyne 是一个用 Go 语言编写的跨平台 GUI 框架&#xff0c;它提供了一套丰富的组件来帮助开发者快速构建出漂亮的用户界面。在本文中&#xff0c;我们将通过一个简单的案例来演示如何使用 Fyne 创建 GUI 应用程序&#xff0c;该程序包含设置标签文本和自增计数器的功能。 …

「字符串」前缀函数|KMP匹配:规范化next数组 / LeetCode 28(C++)

目录 概述 思路 核心概念&#xff1a;前缀函数 1.前缀函数 2.next数组 1.考研版本 2.竞赛版本 算法过程 构建next数组 匹配过程 复杂度 Code 概述 为什么大家总觉得KMP难&#xff1f;难的根本就不是这个算法本身。 在互联网上你可以见到八十种KMP算法的next数组…

项目1 物流仓库管理系统

一、项目概述 本项目旨在开发一个功能全面的物流仓库管理系统&#xff0c;以数字化手段优化仓库作业流程&#xff0c;提高管理效率。系统集成了前端用户交互界面与后端数据处理逻辑&#xff0c;涵盖了从用户注册登录、订单管理、货单跟踪到用户信息维护等多个核心业务模块。通…

基于django的学生作业提交与管理系统,有管理后台,可作为课设使用

在本项目中&#xff0c;我们设计并实现了一个基于Django框架的学生作业提交与管理系统&#xff0c;旨在为教师和学生提供一个高效、便捷的作业管理平台。Django作为一个高效的Web框架&#xff0c;因其强大的功能和灵活的架构&#xff0c;使得本系统能够快速开发并扩展。 系统功…

Maven的简单使用

Maven使用 Maven的作用1. 自动构建标准化的java项目结构(1) 项目结构① 约定目录结构的意义② 约定大于配置 (2)项目创建坐标坐标的命名方法&#xff08;约定&#xff09; 2. 帮助管理java中jar包的依赖(1) 配置使用依赖引入属性配置 (2) maven指令(3) 依赖的范围(4) 依赖传递(…

【密码学】密钥管理:②密钥分配

一、密钥分配的定义 密钥分配是密钥管理生命周期中最重要的部分&#xff0c;密钥分配方案研究的是密码系统中密钥的分发和传送问题。从本质上讲&#xff0c;密钥分配为通信双方建立用于信息加密、解密签名等操作的密钥&#xff0c;以实现保密通信或认证签名等。 &#xff08;1…

华为OD题目 csv格式的数据 字符串 用C没写出来

这题对于嵌入式mcu的人来说&#xff0c;太难为了。不想解了&#xff0c;烂摆。有心情再说把。 将一个csv格式的数据文件中包含有单元格引用的内容替换为对应单元格内容的实际值。 Comma seprated values&#xff08;CSV&#xff09;逗号分隔值&#xff0c;csv格式的数据文件使用…