当前位置: 首页 > news >正文

【C++】滑动窗口算法习题

在这里插入图片描述
🎆个人主页:夜晚中的人海

在这里插入图片描述

今日语录:人生就是这样,要耐的住寂寞,才守得住繁华

文章目录

  • 🚀一、长度最小的子数组
  • 🎉二、无重复字符的最长子串
  • 🚘三、最大连续1的个数 III
  • 🎡四、将x减到0的最小操作数
  • 🏝️五、找到字符中所有字母的异位词
  • ⭐六、串联所有单词的子串

🚀一、长度最小的子数组

题目链接:长度最小的子数组

题目描述:
在这里插入图片描述

解题思路:
1.暴力枚举,枚举任意一个数字当作起始位置,然后从这个位置开始寻找一段最短区间满足 >= target(注:这方法会超时,效率低)

2.滑动窗口,由于题目要的是一段连续的区间,因此我们可以采用滑动窗口的办法。使用两个指针left和right同时指向起始位置,在right小于数组长度前提下,不断向右移动进行累加操作(进窗口)直到它 >= target(判断条件),记录该段区间的长度(更新结果),然后将左端元素划出去(出窗口)同时并判断是否满足条件,如果不满足,则让right++ (进入下一个窗口)

代码实现:

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int ret = INT_MAX,sum = 0;for(int left = 0,right = 0;right < nums.size();right++){sum += nums[right];while(sum >= target){//更新结果ret = min(ret,right - left + 1);sum -= nums[left++];}}return ret == INT_MAX ? 0 : ret;}
};

🎉二、无重复字符的最长子串

题目链接:无重复字符的最长子串

题目描述:
在这里插入图片描述

解题思路:
1.暴力枚举,从每一个位置开始向后,看看无重复字符在什么位置,返回长度最长的那个(注:效率低)

2.滑动窗口 + 哈希表,题目要求依旧是一段连续的区间,因此可以采用滑动窗口的办法。定义两个指针left 和 right,让右端元素right进入窗口(进窗口),并用哈希表统计该字符的频次,如果该字符 > 1(判断条件),则从左侧开始滑出窗口(出窗口),直到该字符的频次为1时,更新结果

代码实现:

class Solution {
public:int lengthOfLongestSubstring(string s) {int hash[128] = {0};int n = s.size();int ret = 0;  for(int left = 0,right = 0;right < n;right++){hash[s[right]]++;while(hash[s[right]] > 1){hash[s[left++]]--;}ret = max(ret,right - left + 1);}return ret;}
};

🚘三、最大连续1的个数 III

题目链接:最大连续1的个数 III

题目描述:
在这里插入图片描述

解题思路:
1.因为该题的要求依旧是一段连续的空间,因此我们可以采用滑动窗口的方法来解决。

2.我们不要想着如何去翻转,把问题复杂化。它的核心就是0的个数不超过k个,我们只要解决这一问题即可

3.可以使用一个变量zero来记录0的个数,用两个指针left和right,right指针负责进窗口,当遇到0时让zero++,直到当zero > k时(判断条件),判断left所指元素是否为0进行出窗口,最后更新结果

代码实现:

class Solution {
public:int longestOnes(vector<int>& nums, int k) {int n = nums.size();int len = 0;for(int left = 0,right= 0,zero = 0;right < n;right++){if(nums[right] == 0){zero++;}while(zero > k){if(nums[left++] == 0){zero--;}}len = max(len,right - left + 1);}return len;}
};

🎡四、将x减到0的最小操作数

题目链接:将x减到0的最小操作数

题目描述:
在这里插入图片描述

解题思路:
由于题目要求的是减去数组左或右两端连续的和为x的最短数组,如果按照题目的要求那我们解决这个问题就比较棘手,由于我们不知道它是减去左边的还是减去右边的,或者连续减去左边等情况,因此我们可以将其进行转化为数组内一段连续的和为sum(nums) - x的最长数组,使用滑动窗口的解法,然后用整个数组的大小减去该段最长数组的大小,我们就得到了题目要求的最短操作数了

代码实现:

class Solution {
public:int minOperations(vector<int>& nums, int x) {int sum = 0;for(auto n : nums){sum += n;}int ret = -1;int target = sum - x;if(target < 0){return -1;}for(int left = 0,right = 0,tmp = 0;right < nums.size();right++){tmp += nums[right];while(tmp > target){tmp -= nums[left++];}if(tmp == target){ret = max(ret,right - left + 1);}}if(ret == -1)return ret;elsereturn nums.size() - ret;}
};

🏝️五、找到字符中所有字母的异位词

题目链接:找到字符中所有字母的异位词

题目描述:
在这里插入图片描述

解题思路:
滑动窗口+ 哈希表,由题可知,字符串p的异位词的长度⼀定与字符串p的长度相同,所以可以在字符串s 中构造⼀个长度为字符串p的长度相同的滑动窗口,用哈希表记录字符串p中字符出现的个数,用一个变量count记录长度,不断进窗口,如果大于异位词的长度并且出现的字符在字符串p中也有(判断条件),就出窗口,让count–,相反就让count++,如果等于字符串p的长度就更新结果

代码实现:

class Solution {
public:vector<int> findAnagrams(string s, string p) {vector<int> ret;int hash1[26] = {0};int n = s.size();int m = p.size();for(auto ch : p){hash1[ch - 'a']++;}int hash2[26] = {0};int count = 0;for(int left = 0,right = 0;right < n;right++){char in = s[right];if(++hash2[in - 'a'] <= hash1[in - 'a']){count++;}if(right - left + 1 > m){   char out = s[left++];if(hash2[out - 'a']-- <= hash1[out - 'a']){count--;}}if(count == m){ret.push_back(left);}}return ret; }
};

⭐六、串联所有单词的子串

题目链接:串联所有单词的子串

题目描述:
在这里插入图片描述

解题思路:
这道题的解法与上道题的异位词解法类似,无非就是把字母转化为一个单词,因此同样采用哈希 + 滑动窗口的解法

代码实现:

class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> ret;unordered_map<string ,int> hash1;for(auto& e:words){hash1[e]++;}int len = words[0].size();int m = words.size();for(int i = 0;i < len;i++){unordered_map<string,int> hash2;for(int left = i,right = i,count = 0;right + len <= s.size();right += len){string in = s.substr(right,len);hash2[in]++;if(hash2[in] <= hash1[in]){count++;}if(right - left + 1 > len * m){string out = s.substr(left,len);if(hash2[out] <= hash1[out]){count--;}hash2[out]--;left += len;}if(count == m){ret.push_back(left);}}}return ret;
http://www.dtcms.com/a/507054.html

相关文章:

  • C语言趣味小游戏----扫雷游戏
  • 三款AI平台部署实战体验:Dify、扣子与BuildingAI深度对比
  • 网站制作难不难小红书搜索优化
  • Python如何使用NumPy对图像进行处理
  • 房产中介网站开发站长工具之家
  • Linux服务器编程实践60-双向管道:socketpair函数的实现与应用场景
  • c++结构体讲解
  • 青岛商城网站建设网站相互推广怎么做
  • Linux学习笔记(九)--Linux进程终止与进程等待
  • 虚幻引擎5 GAS开发俯视角RPG游戏 P06-09 玩家等级与战斗接口
  • JavaSE内容梳理与整合
  • JavaScript日期处理:格式化与倒计时实现
  • 网页与网站设计 什么是属性网站开发用的框架
  • 长沙正规网站建设价格公司概况简介
  • STM32卡尔曼滤波算法详解与实战应用
  • 【自适应粒子滤波 代码】Sage Husa自适应粒子滤波,用于克服初始Q和R不准确的问题,一维非线性滤波。附有完整的MATLAB代码
  • 未来的 AI 操作系统(三)——智能的中枢:从模型到系统的统一
  • 群晖无公网IP内网穿透工具—ZeroNews(零讯)套件详解
  • [日常使用]Anaconda 常见问题排查手册
  • 【Python入门】第3篇:流程控制之条件判断
  • 网站建设初级教程seo高效优化
  • 智能排课系统实战 Java+MySQL实现课程自动编排与冲突检测
  • 【EE初阶 - 网络原理】传输层协议
  • 电子商务网站建设的难点设计创意网站推荐
  • 【Linux环境下安装】SpringBoot应用环境安装(五)-milvus安装
  • Windows使用docker安装milvus的配置文件
  • 记录之Ubuntu22.4虚拟机及hadoop为分布式安装
  • K8s 运维三大核心难题:DNS 故障、有状态存储、AI 赋能 SRE 解决方案
  • c#WPF基础知识
  • 云栖实录|阿里云 Milvus:AI 时代的专业级向量数据库