面试经典 150 题 -- 滑动窗口 (总结)

面试经典150题链接

面试经典 150 题 - 学习计划 - 力扣(LeetCode)全球极客挚爱的技术成长平台

209 . 长度最小的子数组

思路 : 

滑动窗口的思想,取i=j=0,向后遍历j,记录前缀和[l,r]为s,如果s>=target,那么左端点向右移动,直到s<target,维护一个[l,r]的滑动窗口,如此循环;

代码

python

class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:n = len(nums)ans = n+1l=0s=0for r,x in enumerate(nums):s+=xwhile s>=target:ans = min(ans,r-l+1)s-=nums[l]l+=1return ans if ans <= n else 0

c++

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size();if(n==0) return 0 ;int sum = 0;int l = 0 , r = 0 ; int ans = INT_MAX ;while(r < n){sum += nums[r];while(sum >= target){ans = min(ans , r - l + 1) ;sum -= nums[l++];}r++ ;}return ans == INT_MAX ? 0 : ans  ;}
};

 

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

思路 : 

假设在一个无重复元素的字符串后面加上一个字符,如果出现重复元素,那么一定重复的是新加上的那个字符,那么设置一个hash表来统计次数,然后反复将窗口最前面的元素移出窗口,直到将前面与新加元素相同的元素移出时停止;然后循环更新答案即可;

lc题解地址 : 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

代码 : 

Python

class Solution:def lengthOfLongestSubstring(self, s: str) -> int:l = 0cnt = Counter()ans = 0for r , c in enumerate(s):cnt[c]+=1while cnt[c]>=2:cnt[s[l]]-=1l+=1ans = max(ans,r-l+1)return ans


C++

class Solution {
public:int lengthOfLongestSubstring(string s) {unordered_map<char,int> hash;int ans=0;int n = s.size();int l=0;for(int r=0;r<n;r++){hash[s[r]]++;while(hash[s[r]] > 1) --hash[s[l++]];ans = max(ans,r-l+1);}return ans;}
};


java
 

class Solution {public int lengthOfLongestSubstring(String s) {int ans = 0 ;char[] st = s.toCharArray();boolean[] has = new boolean[128] ; int n = s.length();int i = 0 ;for(int j=0;j<n;j++){char c = st[j];while(has[c])has[st[i++]] = false;has[c] = true;ans = Math.max(ans, j-i+1);}return ans;}
}

30 . 串联所有单词的子串

思路 : 

滑动窗口,细节看代码

代码 : 

class Solution {
public:vector<int> findSubstring(string &s, vector<string> &words) {// 一个窗口包含s中的前a个单词;// 先删去前 i (i=0∼b−1)个字母后,// 将剩下的字母进行划分,如果末尾有不到 b 个字母也删去。vector<int> ans ;int a = words.size() , b = words[0].size() , n = s.size() ;for(int i=0;i<b&&i+a*b<=n;i++){ // 对应b种划分方法unordered_map<string,int> mp;for(int j=0;j<a;j++){//将s从i开始的a个长度为b的字符串放入哈希表中++mp[s.substr(i+j*b,b)];}for(string& str : words){//将words中a个的字符串放入哈希表中,放入一个,对应的频次-1if(--mp[str]==0){mp.erase(str);}}for(int start=i;start<n-a*b+1;start+=b){// 非第一个窗口if(start!=i){//因为上面已经考虑过start==i的情况了,这里直接跳过string in = s.substr(start+(a-1)*b,b);//划入新的字符串if(++mp[in]==0){//划入滑动窗口,就++mp.erase(in);}string out = s.substr(start-b,b);if(--mp[out]==0){mp.erase(out);}}if(mp.empty()){// 若窗口内单词与单词表中单词出现频次差皆为0,则为解ans.push_back(start);}}}return ans ;}
};

76 . 最小覆盖子串

滑动窗口 : 

定义两个长度为 606060(足够存下所有字母种类)的数组 c1 和 c2,用于存储字符频率。其中 c1 用于记录字符串 t 中字符的频率,c2 用于记录当前滑动窗口内字符的频率。

设定好字母与频率数组下标的映射关系:小写字母 a-z 对应下标 0-25,大写字母 A-Z 对应下标 26-51。

使用变量 tot 来记录还需要匹配的字符种类数,当 tot = 0 代表当前滑动窗口对应的子串能够实现对 t 的覆盖,即任意字符满足 c2[i]≥c1[i]c2[i] \geq c1[i]c2[i]≥c1[i]。

使用双指针 j 和 i 表示滑动窗口的左右边界。从前往后遍历字符串 s,在每个位置上更新字符频率数组 c2。若 c2 中字符的频率达到了 c1 中的字符频率,则将 tot 减 1,表示一个字符已经匹配完成。

每当右边界往后移动一步之后,滑动窗口会增加一个字符。此时我们检查左边界能否右移,同时不会使得 tot 变大。即每次右边界右移后,我们检查左边界 c2[j]>c1[j]c2[j] > c1[j]c2[j]>c1[j] 是否满足:

若满足:说明当前左边界指向字符并非必须,当前子串 s[j...i]s[j...i]s[j...i] 必然不是最短子串。我们让左边界 j 进行右移,并重复进行左边界 c2[j]>c1[j]c2[j] > c1[j]c2[j]>c1[j] 的检查,直到窗口不能再收缩
若不满足:说明当前窗口没有任何一个后缀字符串能够实现对 t 的覆盖,我们并不能对窗口实现收缩
每次对窗口移动完成后,我们检查当前 tot 是否为 000(对字符串 t 的覆盖是否完成),若为 000 则尝试用当前窗口对应的字符串 s[j...i]s[j...i]s[j...i] 更新 ans。

class Solution {
public:int get(char x) {return x >= 'A' && x <= 'Z' ? x - 'A' + 26 : x - 'a';}string minWindow(string s, string t) {int n = s.size() , cnt = 0 ;// cnt : 还需要匹配的字符种类数// 规定 a-z : 0-25  ,  A-Z : 26-51// c1 用于记录字符串 t 中字符的频率,c2 用于记录当前滑动窗口内字符的频率vector<int> c1(60),c2(60);for(char c : t) if(++c1[get(c)]==1) cnt ++ ;string ans = "" ;for(int i=0,j=0;i<n;i++){int idx1 = get(s[i]);//将s[i]加入窗口if(++c2[idx1]==c1[idx1]) cnt --;while(j<i){int idx2 = get(s[j]);// 尝试将s[j]划出窗口if(c2[idx2]>c1[idx2] && --c2[idx2]>=0){// 能够滑出窗口//;j++;}else{break;//不能够滑出窗口}}if(cnt==0 && (ans.empty() || ans.size()>i-j+1)) ans = s.substr(j,i-j+1);}return ans ;}
};

相似题目 : 

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

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

相关文章

[网络安全 渗透实验 01]基于MSF框架渗透攻击Win7主机系统的设计与实现

基于MSF框架渗透攻击Win7主机系统的设计与实现 文章目录 基于MSF框架渗透攻击Win7主机系统的设计与实现[Warning] 写在前面1. 实验要求2. 实验环境搭建2.1 攻击机&#xff08;Linux kali&#xff09;的下载与安装2.2 靶机&#xff08;Windows 7 Enterprise with Service Pack 1…

iOS图像处理----OpenGL初了解

1&#xff09;什么是渲染上下文&#xff08;Context&#xff09;&#xff1f; OpenGL 自身是一个巨大的状态机&#xff08;State Machine&#xff09;&#xff1a;一系列的变量描述 OpenGL 此刻应当如何运行。OpenGL 的状态通常被称为 OpenGL 上下文&#xff08;Context&#x…

分布式事务(二)—— CAP和Base理论

系列目录&#xff1a; 《分布式事务&#xff08;一&#xff09;—— 事务的基本概念》 一、CAP理论 cap理论是分布式系统的理论基石 1、Consistency[一致性] 即操作成功并返回客户端后&#xff0c;所有节点在同一时间的数据完全一致&#xff0c;这就是分布式的一致性。一致…

Linux------进程优先级与进程切换

目录 一、进程优先级 二、优先级与权限的区别 三、优先级的查看 四、进程优先级修改 五、进程切换 六、linux2.6内核调度队列与调度原理 一、进程优先级 首先我们得知道一个进程总是需要排队的&#xff0c;他一会在运行队列中排队等待运行&#xff0c;一会在设备的等待队…

点云从入门到精通技术详解100篇-基于三维点云花朵特征提取与分割重建(续)

目录 3 花朵点云坐标转换及花朵特征提取 3.1 圆柱坐标系的建立 3.1.1 旋转平移变换

spring-security 默认登录页面

Spring Security是一个强大且高度可定制的身份验证和访问控制框架。天然与Spring整合&#xff0c;易扩展&#xff0c;引入jar包就可以用了&#xff0c;在boot自动装载下&#xff0c;不需要任何配置就可以控制资源访问。那么默认登录页是如何生产的呢&#xff1f; 版本信息 内…

STM32学习笔记(六) —— 配置系统时钟

1.时钟树 从图中可以看出一共有四个时钟来源&#xff0c;分别是内部高速时钟、内部低速时钟、外部高速时钟接口、外部低速时钟接口&#xff0c;这些时钟源经过内部的倍频分频后提供给各外设使用。其中HSE与LSE需要由外部提供&#xff0c;可以是外部时钟直接输入&#xff0c;也可…

C++——输入输出

C——输入输出 1.输入输出 C 中的输入和输出&#xff08;I/O&#xff09;主要是通过标准库中的输入输出流来实现的。最常用的是 iostream 库&#xff0c;它提供了用于输入和输出的基本流类&#xff0c;包括 cin 、 cout 、 cerr 和 clog 。 标准输出流(cout) cout 代表标准…

解决Docker AList本地挂载失效的问题。

解决Docker AList本地挂载失效的问题。 AList Docker version: 3.3 services:alist:image: xhofe/alist:latestcontainer_name: alistvolumes:- ./etc/alist:/opt/alist/data# 比如我要挂载/home,如果在docker里先挂载&#xff0c;是没法办法映射到linux系统下的/home的- /ho…

k8s网络详解(一)

目录 网络概述 Pod 网络通信 Overlay网络 原理 在k8s中的作用 VXLAN 网络插件Flanne Flannel UDP 模式的工作原理 ETCD和Flannel之间的关系 VXLAN 模式 Flannel VXLAN模式跨主机工作原理 网络插件 Calico k8s 组网Calico方案与flannel方案区别 Calico 主要组成部分…

防御保护---防火墙双机热备直路部署(上下三层接口)

防御保护---防火墙双机热备直路部署&#xff08;上下三层接口&#xff09; 一、根据网段划分配置IP地址和安全区域二、配置动态路由OSPF三、配置双机热备四、测试&#xff1a;4.1 测试一&#xff1a;查看状态和路由器路由表&#xff08;双机热备&#xff09;前后对比4.2 测试二…

「数据结构」3.ArrayList

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;**欢迎点赞收藏加关注哦&#xff01;* ArrayList &#x1f349;ArrayList的构造&#x1f349;add方法&#x1f34c;扩容机制&#x1f34c;重要结论 &#x1f349;其…

SQL Server 函数参考手册(SQL Server 日期函数)

目录 SQL Server CURRENT_TIMESTAMP 函数 SQL Server DATEADD() 函数 SQL Server DATEDIFF() 函数 SQL Server DATEFROMPARTS() 函数 SQL Server DATENAME() 函数 SQL Server DATEPART() 函数 SQL Server DAY() 函数 SQL Server GETDATE() 函数 SQL Server GETUTCDATE…

网络协议与攻击模拟_13缓存DNS与DNS报文

一、缓存DNS服务器 1、引入缓存DNS 缓存域名服务器需要与外网连接 一台windows作为Client 一台Windows server作为缓存DNS 桥接网络 DHCP自动获取IP地址 Client 192.168.183.133 Windows server 192.168.183.138 ipconfig /all查看下Client的DNS&#xff0c;设置让Cl…

Unity | 渡鸦避难所-9 | 角色名字及血条等信息

1 效果预览 游戏中角色的名字和血条是非常重要的元素&#xff0c;它们可以帮助玩家了解角色的身份和状态。在 Unity 中&#xff0c;可以使用 UGUI 来实现这些功能 2 实现方案 1 画布 (Canvas) 画布 (Canvas) 组件表示进行 UI 布局和渲染的抽象空间。所有 UI 元素都必须是附加…

【异常处理】word或ppt打开后没反应或闪退,或者报错由安全模式打开

折腾了2个小时&#xff0c;可算解决了&#xff0c;办法是在【控制面板】中右击&#xff0c;选择【更改】 选择联机修复&#xff0c;然后耐心等待&#xff0c;最后再打开就没问题了。

DevOps落地笔记-08|技术债务:勤借勤还,再借不难

上一讲主要介绍了如何有效管理第三方组件的实际案例&#xff0c;目的是让你意识到依赖组件的质量也会影响到软件的质量。前面几个课时谈论的主要内容都是跟软件质量相关&#xff0c;通过各种方式方法提高软件交付的质量。这时就会遇到一个问题&#xff0c;软件质量固然重要&…

2024年第4届IEEE软件工程与人工智能国际会议(SEAI 2024)

2024年第4届IEEE软件工程与人工智能国际会议(SEAI 2024)将于2024年6月21-23日在中国厦门举办。 SEAI旨在为软件工程与人工智能领域搭建高端前沿的交流平台&#xff0c;推动产业发展。本次会议将汇聚海内外的知名专家、学者和产业界优秀人才&#xff0c;共同围绕国际热点话题、核…

Sql Server之更改跟踪功能

1.更改跟踪&#xff08;Change Tracking&#xff09;介绍 更改跟踪是一种轻量型解决方案&#xff0c;它为应用程序提供了一种有效的更改跟踪机制。更改跟踪捕获更改了表行这一事实&#xff0c;但不会捕获更改的数据。 这样&#xff0c;应用程序就可以确定使用从用户表中直接获…

PostGIS空间数据库之空间数据融合实践

目录 前言 一、ST_Union()简介 1、方法说明 2、参数介绍 二、ST_Collect()简介 1、方法说明 2、参数介绍 3、两者区别 三、实际案例实践 1、不重叠融合 2、空间重叠融合 总结 前言 众所周知&#xff0c;熟悉GIS桌面软件的同学一定都知道&#xff0c;想要对空…