LeetCode-刷题记录-滑动窗口合集(本篇blog会持续更新哦~)

一、滑动窗口概述

滑动窗口(Sliding Window)是一种用于解决数组(或字符串)中子数组(或子串)问题的有效算法。

在这里插入图片描述

Sliding Window核心思想:

滑动窗口技术的基本思想是维护一个窗口(一般是一个子数组或子串),该窗口在数组上滑动,并在滑动过程中更新窗口的内容。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

通过滑动窗口,可以在 ( O(n) ) 的时间复杂度内解决很多子数组(子串)问题,其中 ( n ) 是数组(字符串)的长度。

基本步骤:

  1. 初始化窗口: 定义一个窗口的起始位置和结束位置,通常是两个指针 leftright
  2. 滑动窗口: 不断地增加 right 指针来扩大窗口,直到窗口满足某个条件为止。

在这里插入图片描述

  1. 更新窗口: 一旦满足条件,尝试缩小窗口大小,即增加 left 指针,直到条件不满足为止。
  2. 记录结果: 在滑动窗口的过程中,根据题目要求来记录最终的结果。

二、习题合集

LeetCode 209 长度最小的子数组

在这里插入图片描述

  • 滑动窗口O(N)解法:
class Solution {public int minSubArrayLen(int target, int[] nums) {int n = nums.length;  // 数组的长度int ans = Integer.MAX_VALUE;  // 初始化结果为最大值,用于存储最短子数组的长度int l = 0;  // 左指针,指向滑动窗口的起始位置int sum = 0;  // 记录滑动窗口内元素的和for (int r = 0; r < n; r++) {  // 右指针,扩展滑动窗口sum += nums[r];  // 将右指针指向的元素加入窗口while (sum >= target) {  // 当窗口内元素和大于等于目标值时,尝试缩小窗口ans = Math.min(ans, r - l + 1);  // 更新最短子数组的长度sum -= nums[l];  // 缩小窗口,左指针向右移动,减少窗口内的元素和l++;  // 左指针右移}}return ans == Integer.MAX_VALUE ? 0 : ans;  // 如果找不到满足条件的子数组,返回0;否则返回最短子数组的长度}
}

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

在这里插入图片描述


  • 第一版滑动窗口
class Solution {public int lengthOfLongestSubstring(String s) {Map<Character, Integer> map = new HashMap<>(); // 创建一个哈希表,用来记录字符及其出现的最后位置int n = s.length(); // 字符串的长度int l = 0, ans = 0; // l表示当前不重复子串的起始位置,ans用来记录最长不重复子串的长度for (int r = 0; r < n; r++) {char c = s.charAt(r); // 获取当前字符if (map.containsKey(c)) {//如果曾经出现的 字母 还在窗口内 —— l更新到 该位置+1//如果曾经出现的 字母 已不在当前窗口内了—— 则不需要更新l = Math.max(l,map.get(c)+1);}map.put(c, r); // 更新当前字符的最后出现位置为当前索引rans = Math.max(ans, r - l + 1); // 更新最长不重复子串的长度}return ans; // 返回最长不重复子串的长度}
}

要理解 left = Math.max(left,map.get(s.charAt(i)) + 1);需要回归到滑动窗口的原理上。

窗口中始终是无重复字母的字符串。 我们通过窗口的左界和右界控制窗口。

右界不用特意操作,因为它是+1,+1地涨上去,记得在循环里+1就好。

左界:每当有一个字符曾经出现过,就需要判断左界。

重点来了:

若,被判断的字符上一次出现的位置就在滑动窗口内,即 [ i,j ] 内, 则需要left改变位置,改变为该字符上次出现位置+1。也就是left = map.get(s.charAt(i)) + 1的情况。

例如:

abcdb中,窗口正常运行到abcd时,下一个字符为b,b上一次出现在实在窗口里,所以需要把left设置为上一次出现的位置+1的位置,得到新的窗口为cdb,不然你不这样设置,窗口里有重复的字符(bcdb),不符合窗口的定义。

若,不在滑动窗口内,则不用管。 不用管是因为:窗口中字符串没有重复字符。窗口符合定义。所以left = left。 left = left就表示这个窗口暂时不变。

在这里插入图片描述


  • 第二版优化的滑动窗口:
class Solution {public int lengthOfLongestSubstring(String s) {// 记录字符上一次出现的位置int[] last = new int[128]; // 创建一个长度为128的整型数组,用来记录ASCII码表中每个字符上一次出现的位置for(int i = 0; i < 128; i++) {last[i] = -1; // 初始化数组,所有字符的上一次出现位置都设为-1,表示尚未出现过}int n = s.length(); // 字符串s的长度int res = 0; // 用于记录最长的不重复子串的长度int start = 0; // 窗口开始位置,用来维护当前不重复子串的起始位置for(int i = 0; i < n; i++) {int index = s.charAt(i); // 获取当前字符的ASCII码作为索引start = Math.max(start, last[index] + 1); // 更新窗口的起始位置,确保不重复的起点res = Math.max(res, i - start + 1); // 更新最大的不重复子串长度last[index] = i; // 更新当前字符的最后出现位置为当前索引i}return res; // 返回最长的不重复子串的长度}
}

LeetCode 187 重复的DNA序列

在这里插入图片描述

  • 哈希表法~
class Solution {public List<String> findRepeatedDnaSequences(String s) {List<String> ans = new ArrayList<>(); // 用于存放重复的DNA序列int n = s.length(); if (n < 10) return ans; // 如果字符串长度小于10,直接返回空列表,因为无法形成长度为10的序列Map<String, Integer> map = new HashMap<>(); // 创建一个哈希表,用来记录每个长度为10的子序列及其出现的次数map.put(s.substring(0, 10), 1); // 初始化,将第一个长度为10的子序列放入哈希表中for (int i = 1; i + 10 <= n; i++) { // 从第二个子序列开始遍历到倒数第十个子序列String ss = s.substring(i, i + 10); // 获取当前长度为10的子序列if (map.getOrDefault(ss, 0) == 1) { // 如果该子序列已经在哈希表中出现过一次ans.add(ss); // 将该子序列加入结果列表}map.put(ss, map.getOrDefault(ss, 0) + 1); // 更新哈希表中该子序列的出现次数}return ans; // 返回重复的DNA序列列表}
}
  • 滑动窗口法~
class Solution {// 滑动窗口法查找重复的长度为10的DNA序列public List<String> findRepeatedDnaSequences(String s) {List<String> ans = new ArrayList<>(); // 用于存放重复的DNA序列int n = s.length(); // 字符串的长度if (n < 10) return ans; // 如果字符串长度小于10,直接返回空列表,因为无法形成长度为10的序列StringBuilder sb = new StringBuilder(s.substring(0, 10)); // 初始化第一个长度为10的子串Set<String> set = new HashSet<>(); // 使用集合来记录出现过的子串set.add(sb.toString()); // 将第一个子串添加到集合中for (int i = 1; i + 10 <= n; i++) {String str = s.substring(i, i + 10); // 获取当前长度为10的子串if (set.contains(str)) { // 如果集合中已经包含当前子串if (!ans.contains(str)) // 且列表中还未包含该子串ans.add(str); // 将该子串添加到列表中} else { // 如果集合中不包含当前子串set.add(str); // 将当前子串添加到集合中}}return ans; // 返回存放了重复DNA序列的列表}
}

LeetCode 424 替换后的最长重复字符

在这里插入图片描述
在这里插入图片描述

  • 核心思想:

相同的最长子字符串(窗口) = 窗口内最大字符个数 + 反转次数

一旦 窗口长度 - 窗口内最大字符个数 > 反转次数 窗口开始移动

public int characterReplacement(String s, int k) {int n = s.length();if(n<2) return n;int ans = 0; // 用于存储最长连续相同字符的子串的长度int maxFreq = 0; // 用于存储当前窗口内出现次数最多的字符的次数char[] c = s.toCharArray();int[] freq = new int[26]; // 记录当前窗口内每个字符出现的次数int left = 0; // 滑动窗口的左边界for (int right = 0; right < n; right++) {++freq[c[right] - 'A']; // 更新右边界字符的出现次数maxFreq = Math.max(maxFreq, freq[c[right] - 'A']); // 更新最大出现次数// 如果当前窗口的大小减去出现次数最多的字符的次数大于k,则需要缩小窗口// 使得窗口内可以通过替换字符使其变成连续相同字符的子串if (right - left + 1 > maxFreq + k) {freq[c[left] - 'A']--; // 缩小窗口时,更新左边界字符的出现次数left++; // 缩小窗口}// 更新最长连续相同字符的子串的长度ans = Math.max(ans, right - left + 1);}return ans;}


更新于:

在这里插入图片描述

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

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

相关文章

怎样在Python中使用oobabooga的API密钥,通过端口5000获取模型列表的授权

题意&#xff1a; oobabooga-textgen-web-ui how to get authorization to view model list from port 5000 via the oobas api-key in python 怎样在Python中使用oobabooga的API密钥&#xff0c;通过端口5000获取模型列表的授权 问题背景&#xff1a; I wish to extract an…

fastapi+vue3前后端分离开发第一个案例整理

开发思路 1、使用fastapi开发第一个后端接口 2、使用fastapi解决cors跨域的问题。cors跨域是浏览器的问题&#xff0c;只要使用浏览器&#xff0c;不同IP或者不同端口之间通信&#xff0c;就会存在这个问题。前后端分离是两个服务&#xff0c;端口不一样&#xff0c;所以必须要…

PCA和PCoA分析的python代码

主成分分析(PCA)和主坐标分析(PCoA)都是数据降维和可视化的常用方法,但它们在适用场景和计算方法上有一些重要区别。 主成分分析(PCA) 定义: PCA是一种线性降维方法,通过正交变换将原始数据转化为一组线性不相关的变量(主成分)。这些主成分是数据中方差最大的方向。…

XLSX + LuckySheet + LuckyExcel实现前端的excel预览

文章目录 功能简介简单代码实现效果参考 功能简介 通过LuckyExcel的transformExcelToLucky方法&#xff0c; 我们可以把一个文件直接转成LuckySheet需要的json字符串&#xff0c; 之后我们就可以用LuckySheet预览excelLuckyExcel只能解析xlsx格式的excel文件&#xff0c;因此对…

.NET 漏洞分析 | 某ERP系统存在SQL注入

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

Java中s-EJB 与 e-EJB的区别

在Java中&#xff0c;关于“s-EJB”与“e-EJB”的区分&#xff0c;实际上可能存在一定的误解或混淆&#xff0c;因为在标准的EJB&#xff08;Enterprise JavaBeans&#xff09;术语中&#xff0c;并没有直接称为“s-EJB”和“e-EJB”的明确分类。然而&#xff0c;为了尝试解答这…

【Postman gRPC测试全攻略】探索微服务通信的新纪元

标题&#xff1a;【Postman gRPC测试全攻略】探索微服务通信的新纪元 gRPC是一种高性能、开源和通用的RPC框架&#xff0c;由Google主导开发&#xff0c;它使用Protocol Buffers作为接口描述语言和消息交换格式。Postman作为API开发的利器&#xff0c;也提供了对gRPC服务的测试…

封装2个函数

1 #include "key1.h"2 //封装EXTI章节函数3 void hal_exti_init(int exti,unsigned int i)4 {5 switch(exti)6 {7 case 9:8 //使能GPIOF外设时钟9 RCC->MP_AHB4ENSETR | (0x1<<5);10 //将PF9设置为输出模式11 …

MyBatis(22)如何在 MyBatis 中使用注解而不是 XML 映射文件

在 MyBatis 中&#xff0c;使用注解而不是 XML 映射文件来进行 SQL 映射是一种更为简洁直观的方式&#xff0c;尤其适用于 SQL 语句较少的场景。通过注解&#xff0c;开发者可以直接在接口方法上声明 SQL 语句&#xff0c;这样可以减少项目中的配置文件数量&#xff0c;使得项目…

学习笔记——动态路由——OSPF(认证)

十二、OSPF邻居认证 1、OSPF邻居认证概述 链路是路由器接口的另一种说法&#xff0c;因此OSPF也称为接口状态路由协议。OSPF通过路由器之间通告网络接口的状态来建立链路状态数据库&#xff0c;生成最短路径树&#xff0c;每个OSPF路由器使用这些最短路径构造路由表。 OSPF认…

基于Vue框架实现的记事本

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>懒人记事本</title><style>body {fo…

深度网络现代实践 - 深度前馈网络之反向传播和其他的微分算法篇

序言 反向传播&#xff08;Backpropagation&#xff0c;简称backprop&#xff09;是神经网络训练过程中最关键的技术之一&#xff0c;尤其在多层神经网络中广泛应用。它是一种与优化方法&#xff08;如梯度下降法&#xff09;结合使用的算法&#xff0c;用于计算网络中各参数的…

大数据面试题之数仓(1)

目录 介绍下数据仓库 数仓的基本原理 数仓架构 数据仓库分层(层级划分)&#xff0c;每层做什么?分层的好处? 数据分层是根据什么? 数仓分层的原则与思路 知道数仓建模常用模型吗?区别、优缺点? 星型模型和雪花模型的区别?应用场景?优劣对比 数仓建模有哪些方式…

【Symfony社区全接触】深入探索文档与支持资源

标题&#xff1a;【Symfony社区全接触】深入探索文档与支持资源 Symfony是一个强大的PHP框架&#xff0c;拥有一个活跃的开发者社区和丰富的文档资源。这些资源对于学习和使用Symfony至关重要。本文将详细介绍Symfony的文档和社区支持&#xff0c;包括官方文档、社区论坛、邮件…

如何计算弧线弹道的落地位置

1&#xff09;如何计算弧线弹道的落地位置 2&#xff09;Unity 2021 IL2CPP下使用Protobuf-net序列化报异常 3&#xff09;编译问题&#xff0c;用Mono可以&#xff0c;但用IL2CPP就报错 4&#xff09;Wwise的Bank在安卓上LoadBank之后&#xff0c;播放没有声音 这是第393篇UWA…

02 数据加工层 如何搭建用户与内容的标准规范体系

你好&#xff0c;我是周大壮。 01 讲我们提到了个性化流量分发体系的四个阶段&#xff0c;并着重讲解了数据采集阶段的内容。那么&#xff0c;这一讲我们主要围绕数据加工阶段的内容进行详细讲解。 在课程开始之前&#xff0c;我们先举一个场景进行说明。 近年来&#xff0c…

静态方法与实例方法的区别

静态方法与实例方法的区别 1、静态方法&#xff08;Static Methods&#xff09;1.1 调用方式1.2 访问权限 2、实例方法&#xff08;Instance Methods&#xff09;2.1 调用方式2.2 访问权限 3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1…

大数据面试题之数仓(2)

目录 维度表和事实表的区别? 什么是ER模型? OLAP、OLTP解释(区别)三范式是什么&#xff0c;举些例子 维度设计过程&#xff0c;事实设计过程 维度设计中有整合和拆分&#xff0c;有哪些方法&#xff0c;并详细说明 事实表设计分几种&#xff0c;每一种都是如何在业…

【C++】解决 C++ 语言报错:Invalid Array Index

文章目录 引言 无效数组索引&#xff08;Invalid Array Index&#xff09;是 C 编程中常见且危险的错误之一。当程序试图使用不合法的索引访问数组时&#xff0c;就会发生无效数组索引错误。这种错误不仅会导致程序崩溃&#xff0c;还可能引发不可预测的行为和安全漏洞。本文将…

【PB案例学习笔记】-28制作一个右键菜单

写在前面 这是PB案例学习笔记系列文章的第28篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…