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

基础算法精讲 03 | 滑动窗口|ASCII表如如何使用|substr函数

滑动窗口用于数组/字符串 中求子数组/子串。
右指针的右移很好处理。滑动窗口的难点在于找到移动左指针的条件!!!
滑动窗口的模板是

for(r指针向右遍历)while(碰到某种情况,l指针向右移)

209.长度最小的子数组

209. 长度最小的子数组

思路

  1. 一看题目【长度最小】【子数组】就知道是滑动窗口的zoom了
  2. 数组求子数组,用滑动窗口
  3. 有一个长度最小的逻辑。
 int length = r - l + 1;res = min(res, length);

完整代码

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

二刷11.1

连滑动窗口模板都想不起来。写的一塌糊涂。

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

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

思路

  1. 【最长】【子串】使用滑动窗口。
  2. 窗口中用哈希表来记录出现次数。如apple。当窗口滑动到ple时,就是最长无重复的子串。pple是因为p出现了2次,窗口还是会右移。

完整代码

class Solution {
public:int lengthOfLongestSubstring(string s) {int res = 0;int mres = 0;int l = 0;unordered_map<char, int> p;for (int r = 0; r < s.size();r++){p[s[r]]++;while(p[s[r]]!=1){p[s[l]]--;l++;}mres = (r - l + 1);if(mres > res )res = mres;          }return res;}
};

出现的问题

  1. unordered_map底层是由哈希表构成的。访问很直接p[ s[ i ] ]。
    2. 关于最长字串/最短子串的思考
    我原本是用一个if判断写的,有点麻烦了。
//最长子串
for(int i=0;i<s.size();i++){res=max(res,i-l+1);}

//最短子串

for(int i=0;i<s.size();i++){res=min(res,i-l+1);}

二刷

哈希想到了,不会定义(😓)

713.乘积小于K的子数组

713. 乘积小于 K 的子数组

思路

  1. 在数组中找子数组。用滑动窗口。
  2. 左指针是要右移的,如果按条件中的while(sum<k)来,左指针反而还得左移。。。
  3. 窗口中哪些才算子数组了?比如现在窗口是【5,2,6】.那子数组就应该是【6】,【2,6】,【5,2,6】.。那些【2】,【5,2】是右指针在2时窗口下的子数组。
  4. 怎么计算个数了?r-l+1

完整代码

class Solution {
public:int numSubarrayProductLessThanK(vector<int>& nums, int k) {//当k <= 1时,下面的左指针右移会陷入循环,nums[l]会越界,堆溢出。if (k <= 1) return 0;int res = 0;int sum = 1;int l = 0;for (int r = 0; r < nums.size() ;r++){sum *= nums[r];while(sum>=k){sum /= nums[l];l++;}res+=(r-l+1);}return res;}
};

出现的错误

  1. 在左指针移动这里我出现的错误。我习惯性写成了while(sum<k),这样的逻辑左指针是无法向右移动的。经典的错误。
while(sum<k){}

二刷

heap-buffer-overflow堆溢出,就是数组越界,就是边界条件没有处理好。

在这里插入图片描述
vecto对象在栈上,但数据在堆上。这么理解。
就是vector这个类中,有指针,有int型。指针指向堆上的数据。指针是在栈上,指向堆上的一种数据类型。

在这里插入图片描述

2958. 最多 K 个重复元素的最长子数组

2958. 最多 K 个重复元素的最长子数组

思路

  1. 用哈希表统计元素出现的次数

完整代码

class Solution {
public:int maxSubarrayLength(vector<int>& nums, int k) {int length =0;int l=0;int res=0;//哈希表unordered_map<int,int> p;for(int r=0;r<nums.size();r++){p[nums[r]]++;while(p[nums[r]]==k+1){p[nums[l]]--;l++;}length=r-l+1;res=max(res,length);}return res;}
};

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

没意思不用写

1004. 最大连续1的个数 III

思路

  1. 有一点点逆向思维,滑动窗口中数0的个数

完整代码

class Solution {public:int longestOnes(vector<int>& nums, int k) {int res = 0;int length = 0;int l = 0;int zeroCount = 0;    for (int r = 0; r < nums.size();r++){if(nums[r]==0)zeroCount++;while(zeroCount>k){if(nums[l]==0)zeroCount--;l++;}length = r - l + 1;res = max(res, length);}return res;}
};

2962. 统计最大元素出现至少 K 次的子数组

太偏了

2302. 统计得分小于 K 的子数组数目

2302. 统计得分小于 K 的子数组数目

思路

  1. 很简单呀。难点在于 (1 + 2 + 3 + 4 + 5) * 5 = 75 。这个式子如何实现。将加法和长度分开计算即可。

完整代码

class Solution {
public:long long countSubarrays(vector<int>& nums, long long k) {long long sum = 0;int length = 0;long long count = 0;int l = 0;for (int r = 0; r < nums.size(); r++) {sum += nums[r];length = r - l + 1;//sum * length实现 (1 + 2 + 3 + 4 + 5) * 5 = 75 while (sum * length >= k) {sum -= nums[l];l++;//更新最新的长度length = r - l + 1;}//子数组的数目需要研究一下count += (r - l + 1);}return count;}
};

1658. 将 x 减到 0 的最小操作数

1658. 将 x 减到 0 的最小操作数

思路

  1. 逆向思维。这题用滑动窗口的意图很明显。最小操作数==》剩余元素的最长子串。
  2. 移除的是 nums 最左边或最右边的元素,那么剩下的元素是什么?是 nums 的连续子数组。

移除的元素和 x + 剩余的元素和 = nums 的所有元素之和 s。
所以剩余的元素和 = s−x。
问题变成:
从 nums 中找最长的子数组(这样移除的数尽量少),满足子数组的元素和恰好等于 s−x。

完整代码

class Solution {
public:int minOperations(vector<int>& nums, int x) {//逆向思维int target = reduce(nums.begin(), nums.end()) - x;//如果x设定的太大了,就找不到子数组使target<0if(target<0)return -1;//如果x==整个数组加起来,也要单独拎出来if(target ==0)return nums.size();int sum = 0;int length = 0;int res = 0;int l=0;for(int r=0;r<nums.size();r++){sum+=nums[r];while(sum>target){sum-=nums[l];l++;}//如果有子数集==targetif(sum==target){length=r-l+1;res=max(res,length);}}//如果没有子数集==targetif(length==0)return -1;return nums.size()-res;}
};

遇到的问题

在我没有把if(target<0) 和 if(target ==0)写出来时,编译器会报错堆溢出,数组越界。以后碰到堆溢出,就知道是边界条件没有处理好了。

76. 最小覆盖子串

思路

  1. 【最小】【子串】肯定是用滑动窗口。
  2. 滑动窗口的左滑条件是 s 覆盖 t 。怎么判断s 覆盖 t 呢

    用两个数组将SCII表的0~127全部表示。比如cnt_t[65]=3,就表示t串中有3个’A’。
    然后遍历ASCII表,如果cnt_s中每一个值都大于cnt_t,则是全覆盖。

  3. 需要用substr(起点,长度)函数来返回子串。
  4. 如果s不覆盖t,应该怎么写返回值呢?

s覆盖t时,会进入while(is_covered(cnt_s,cnt_t)),一定会L++的。所以l==0就是s不覆盖t的情况。

完整代码

class Solution {
public://s是否“覆盖”tbool is_covered(int cnt_s[],int cnt_t[]){for(int i='A';i<='Z';i++){if(cnt_s[i]<cnt_t[i])return false;}for(int i='a';i<='z';i++){if(cnt_s[i]<cnt_t[i])return false;}return true;}string minWindow(string s, string t) {//定义一个128数组用来存说有可能出现的ascii值int cnt_s[128]{};//再定义一个用来存储tint cnt_t[128]{};int l=0;int r=0;//用来记录s覆盖t时可能的长度.resL,resR是字符串索引int resL=0;int resR=s.size()-1;int length=resR-resL+1;//将t中的数据放入哈希表中for(int i=0;i<t.size();i++){cnt_t[t[i]]++;}for(;r<s.size();r++){cnt_s[s[r]]++;//cnt_s是否已经 覆盖 cnt_twhile(is_covered(cnt_s,cnt_t)){//此时记录s覆盖t时的长度,resL和resR。因为后面输出子串时需要if(length > r-l+1){length=r-l+1;resL=l;resR=r;}cnt_s[s[l]]--;l++;}}//如果s没有覆盖tif(l==0)return "";elsereturn s.substr(resL,length);}
};

遇到的问题

  1. 如和使用ASCII表
    ’A‘ ======65
    for(int i=‘A’;i<=‘Z’;i++),用int型i遍历ASCII表。A也必须加单引号,不加单引号A就是变量了。

  2. substr(起点,长度)

http://www.dtcms.com/a/561058.html

相关文章:

  • 中国建设银行官网首页 网站首页网站文件目录结构
  • GitHub Actions for AI:构建企业级模型CI/CD流水线
  • DevOps——CI/CD持续集成与持续交付/部署的理解与部署
  • 建立网站的公司平台七牛云存储 wordpress连接失败
  • 利用DeepSeek辅助修改luadbi-duckdb读取DuckDB decimal数据类型
  • 深圳网站设计网站制作深圳网站建设推进
  • 电力电子技术 第十三章——PWM逆变器
  • 网站建设方案应该怎么写wordpress用户评论图片
  • xtuoj 2021
  • 数据科学每日总结--Day8--数据挖掘
  • 达梦DEM监控工具部署
  • 机器学习实践项目(二)- 房价预测 - 认识数据
  • 李宁运动服网站建设规划书网站内链少改怎么做
  • 安装JDK安装GIT安装IDEA
  • 定制报表系统设计与实现
  • 最具价值的网站建设商业策划公司十大公司
  • 网站开发设计公东莞智通人才招聘网官网
  • 【BFS 解决FloodFill 算法】3. 岛屿的最⼤⾯积(medium)
  • 【JUnit实战3_23】 第十四章:JUnit 5 扩展模型(Extension API)实战(上)
  • python_study--week3
  • 【Excalidraw】简洁好看的超轻量级画图白板
  • 手写Autosar架构的CAN通讯协议栈2(CanIf模块详解-上)
  • 【Agentic RL 专题】三、深入浅出强化学习算法 TRPO 和PPO
  • 中国最好的建站公司毕业设计模板
  • 《算法通关指南:数据结构和算法篇 --- 栈相关算法题》--- 1. 【模板】栈,2.有效的括号
  • 高效管理搜索历史:Vue持久化实践
  • html网站架设目录和文章wordpress
  • Rust 编程语言基础知识全面介绍
  • 洛龙区网站制作建设费用做网站一般用什么语言
  • 计算机网络---基础诊断ping