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

滑动窗口算法-day7(越长越合法子数组)

1.包含所有三种字符的子字符串

题目

解析

1.解析

  • 遍历右指针,当满足条件的时候,再去收缩左指针,达到不满足条件;
  • 此时左指针 L 的值即为当前滑窗下的答案,继续遍历;

代码

class Solution {
public:int numberOfSubstrings(string s) {// 时间复杂度:O(n)// 空间复杂度:O(3)int n = s.size();int ans = 0;unordered_map<char,int> cnt;int l = 0;for(int r = 0;r < n;r ++){ // 遍历右指针cnt[s[r]] ++;// 在满足条件情况下,不断收缩左指针,直到不满足while(cnt['a'] > 0 && cnt['b'] > 0 && cnt['c'] > 0){cnt[s[l]] --;l ++;}ans += l; // 此时 l 就是该滑窗条件下对应答案数}return ans;}
};

2.字符至少出现 K 次的子字符串 I

题目

解析

  • 同理可得

代码

class Solution {
public:int numberOfSubstrings(string s, int k) {// 时间复杂度:O(n)// 空间复杂度:O(k)int n = s.size();int ans = 0;unordered_map<char,int> cnt;int l = 0;for(int r = 0;r < n;r ++){cnt[s[r]] ++;while(cnt[s[r]] >= k) {cnt[s[l]] --;l ++;}ans += l;}return ans;}
};

3.统计完全子数组的数目

题目

解析

  • 同理可得

代码

class Solution {
public:int countCompleteSubarrays(vector<int>& nums) {// 时间复杂度:O(n)// 空间复杂度:O(n)int n = nums.size();int ans = 0;// unordered_set 自动去重,再利用.size()得到不同元素个数int x = unordered_set<int>(nums.begin(),nums.end()).size();unordered_map<int,int> cnt;int l = 0;for(int r = 0;r < n;r ++){cnt[nums[r]] ++;while(cnt.size() == x) {cnt[nums[l]] --;if(cnt[nums[l]] == 0) cnt.erase(nums[l]);l ++;}ans += l;}return ans;}
};

4.统计好子数组的数目

题目

解析

1.解析

  • 核心:用 sum = cnt[nums[i]] 记录“下标对”的数目

代码

class Solution {
public:long long countGood(vector<int>& nums, int k) {// 时间复杂度:O(n)// 空间复杂度:O(n)int n = nums.size();long long ans = 0;int pairs = 0;unordered_map<int,int> cnt;    int l = 0;for(int r = 0;r < n;r ++){pairs += cnt[nums[r]]; // 记录有几对下标cnt[nums[r]] ++; while(pairs >= k){cnt[nums[l]] --;pairs -= cnt[nums[l]];l ++;} ans += l;}return ans;}
};

 5.统计重新排列后包含另一个字符串的子字符串个数 II

题目

解析

  • 与《最小覆盖子串》是一样的解法;
  • 核心思想:当子串可以包含字符串,经过重排,就能使得它覆盖字符串;当我们找到了最长包含字符串所有元素的子串时,收缩左端点,直到不能完全覆盖,此时答案 + L;

代码

class Solution {
public:long long validSubstringCount(string word1, string word2) {// 时间复杂度:O(n)// 空间复杂度:O(k)int n = word1.size();int less = 0;long long ans = 0;unordered_map<char,int> cnt;for(char c : word2) {if(cnt[c] == 0) less ++;cnt[c] ++; }int l = 0;for(int r = 0;r < n;r ++){cnt[word1[r]] --;if(cnt[word1[r]] == 0) less --;while(less == 0){if(cnt[word1[l]] == 0) less ++;cnt[word1[l]] ++;l ++;}ans += l;}return ans;}
};

6.总结

  • 统一规律: ans += left;
  • 遍历右指针,当满足条件的时候,再去收缩左指针,达到不满足条件;
  • 此时左指针 L 的值即为当前滑窗下的答案,继续遍历;
  • 原理:答案每次加的都是以右指针元素为核心的个数,在最短子数组情况下,左边加多少元素仍然满足条件,可以看出越长越合法,因此答案 + L ;

http://www.mrgr.cn/news/93955.html

相关文章:

  • 18、函数的反柯里化
  • SpringMVC 基本概念与代码示例
  • 【git】 贮藏 stash
  • 《 C++ 点滴漫谈: 三十 》高手写 C++,参数这样传才高效!你真的用对了吗?
  • 【git】删除已加入 .gitignore却仍被git追踪的文件
  • 1分钟看懂React的那些Hook‘s
  • java每日精进 3.11 【多租户】
  • 【性能测试】Jmeter详细操作-小白使用手册(2)
  • win10安装部署DB-gpt,坑多
  • 【Linux docker】关于docker启动出错的解决方法。
  • git规范提交之commitizen conventional-changelog-cli 安装
  • cu118 安装vllm 极简教程 踩坑笔记
  • [pytest] 配置
  • 【08】单片机编程核心技巧:变量命名规范
  • DeepSeek大语言模型下几个常用术语
  • 创建Electron35 + vue3 + electron-builder项目,有很过坑,记录过程
  • 【模拟CMOS集成电路设计】带隙基准(Bandgap)设计与仿真(基于运放的电流模BGR)
  • 从0开始的操作系统手搓教程43——实现一个简单的shell
  • 【SpringMVC】深入解析@ RequestMapping 注解的概念及使用和 MVC 介绍
  • QT多线程