定长滑动窗口--灵神题单(一刷进阶)

简介: 这篇文章主要围绕灵神题单中的定长滑动窗口进阶题进行探讨,首先解决了一些基本题目,然后附带了一些相对困难题目的解题思路。值得注意的是,大部分解答都是在前人的基础上进行了一些小的修改和调整。希望文章对大家的学习和解题能力有所帮助。如果您需要更具体的内容或者对某一部分有兴趣深入讨论,请告诉我!


目录

第一题:2134. 最少交换次数来组合所有的 1 II - 力扣(LeetCode)

按照力扣的 滑动窗口 标签刷到这题,知道是滑窗,但想了半天没想到怎么滑。
再看了下灵神给的滑动窗口题单【题单】滑动窗口(定长/不定长/多指针) 里面把这题归类为定长滑动窗口。
说是定长滑窗。那只能是 1的总数 或 0的总数 当作固定的窗口长度吧。
那就两种情况都写一下,反正都是O(n)。
窗口长度固定为0的总数,那窗口内 要被替换成0的个数,即窗口内1的个数就是结果,求最小
窗口长度固定为1的总数,那窗口内 要被替换成1的个数,即窗口内0的个数就是结果,求最小
上述两个结果都求出来,然后再求个最小,然后就通过了。
定长滑窗的具体写法是 初始窗口处理好,然后右端进一个,左端出一个。
class Solution {
public:
int minSwaps(vector& nums) {
int n = nums.size();
int count_1 = 0;// 统计一的个数
for (auto& num : nums) count_1 += num;
int count_0 = n - count_1;
int ret = n;
for (int left = 0, right = 0, count = 0; right < n; right++)
{
// 进窗口
count += nums[right];
// 判断
if (right - left + 1 >= count_1)
{
ret = min(ret, count_1 - count);
count -= nums[left++];
}
}
for (int left = 0, right = 0, count = 0; right < n; right++)
{
// 进窗口
if (nums[right] == 0)
{
count += 1;
}
// 判断
if (right - left + 1 >= count_0)
{
ret = min(ret, count_0 - count);
if (nums[left++] == 0) count -= 1;
}
}
return ret;
}
};
第二题:567. 字符串的排列 - 力扣(LeetCode)

这一道题如果想到要去使用哈希表,其实是非常的简单的,最主要的是如何想办法去优化。

检查字符串s2是否包含s1的排列。你通过hash1记录s1中每个字符的频率,并通过hash2跟踪当前窗口内字符的频率。每次滑动窗口时,更新字符的计数并检查是否满足s1的字符频率。优化点在于:1. 通过滑动窗口避免重复遍历,

  1. 只对s1中出现的字符进行操作,减少不必要的计算。通过count变量追踪窗口中字符的匹配数量,避免了每次都重新计算。

class Solution {
public:
bool checkInclusion(string s1, string s2) {
int n1 = s1.size();
int n2 = s2.size();
if (n1 > n2)
return false; // 如果s1的长度大于s2,直接返回false
unordered_map hash1;
for (auto& e : s1)
hash1[e]++;
unordered_map hash2;
for (int left = 0, right = 0, count = 0; right < n2; right++) {
// 进窗口
char in = s2[right];
if (hash1.find(in) != hash1.end()) {
hash2[in]++;
if (hash2[in] <= hash1[in])
count++;
}
// 判断 出
if (right - left + 1 >= n1)
{
if (count == n1)
{
return true;
}
char ou = s2[left++];
if (hash1.find(ou) != hash1.end())
{
// 如果移出的字符在 s1 中出现过,更新 hash2 和 count
if (hash2[ou] <= hash1[ou])
{
count--;
}
hash2[ou]--;
}
}
}
return false;
}
};
第三题:438. 找到字符串中所有字母异位词 - 力扣(LeetCode)

这一道题其实也是非常简单的定长滑动窗口。没什么难度。就不解释了,直接给代码吧。

但是还是要给出疑问:

使用哈希表好?还是数组好? 给出为什么?

class Solution {
public:
vector findAnagrams(string s, string p) {
int hash1[26]={0};
int m=p.size();
for(auto& e:p) hash1[e-'a']++;
int hash2[26]={0};
int n=s.size();
vector ret;
for(int left=0,right=0,count=0;rightm )
{
if(hash2[ou-'a']--<=hash1[ou-'a']) count--;
left++;
}
//更新结果
if(count==m)
{
ret.push_back(left);
}
}
return ret;
}
};
第四题:2156. 查找给定哈希值的子串 - 力扣(LeetCode)

这一道题其实也是不是很难,虽然力扣给出是困难题,但是只要了解一些数学知识,把题目的过程简化,难度连中等题都谈不上。

但这一切前提都是你对该部分数学知识了解,如果不了解,根本无思路。

推荐文章:分享丨模运算的世界:当加减乘除遇上取模(模运算恒等式/费马小定理) - 力扣(LeetCode)

代码:

class Solution {
public:
string subStrHash(string s, int power, int modulo, int k, int hashValue) {
int n=s.size();
string ret;
int h = 0; // 子串哈希值
for(int left=0,right=0;right=k)
{
if(h==hashValue)
{
ret=s.substr(left,k);
}
// 出
if(h==0) h=modulo;
h=(long long)h-(s[left++]-'a'+1)* power % modulo;
}
}
return ret;
}
};
第五题:1016. 子串能表示从 1 到 N 数字的二进制串 - 力扣(LeetCode)
看到这一题的时候我也是一头雾水,但是看过灵神写的题解,才慢慢反应过来。

灵神首先给出的是暴力求解

对于方法一,其实我开始也看不明白代码什么意思

class Solution {
public:
bool queryString(string s, int n) {
for(int i=1;i<=n;i++)
{
auto bin = bitset<32>(i).to_string();
bin = bin.substr(bin.find('1'));
if(s.find(bin) == -1) return false;
}
return true;
}
};
这里使用gtp解释一下

对于方法二:

直接截图看灵神的解释吧,人家写的太详细了,想的太妙了,尤其是其中的(x << 1) | (c - '0')。

但是妙归妙,还是要看完思路,自己尝试首先一下代码。

class Solution {
public:
bool queryString(string s, int n) {
unordered_set ans;
for(int i=0,m=s.size();i<m;i++)
{
int x=s[i]-'0';
if(x==0) continue;// 二进制为,继续
for(int j=i+1;x<=n;j++)
{
ans.insert(x);
if(j==m) break;
x=(x<<1) | (s[j]-'0');
}
}
return ans.size()==n;
}
};
第六题:2269. 找到一个数字的 K 美丽值 - 力扣(LeetCode)

这道题要说它简答吧,直接暴力硬写也可以写出来,但是要说它简单,但要使用滑动窗口来写,又比较麻烦。

思路好想,没什么难度,直接给代码

class Solution {
public:
int divisorSubstrings(int num, int k) {
vector v; //存放num这个数串每个位的值
int n; //代表数串每个位数的值
int num1 = num; //将num赋给num1
int res = 0;//美丽值-返回的结果
while(num1 != 0){//从个位 十位 百位...依次压入v容器中
n = num1%10;//余数
num1 = num1/10;//自除更新num1
v.push_back(n);
}
reverse(v.begin(),v.end());//逆序v容器的元素
int left = 0;//左边界
int right = k-1;//右边界 //0到k-1正好k个数
for(left,right;right<v.size();right++,left++){//滑动窗口方式模拟验证
int tmp = v[left];//初始化tmp 滑动窗口左边界代表 窗口内数串的最高位
for(int i=left+1;i<=right;i++){
tmp = tmp*10+v[i]; //模拟滑动窗口中元素组成一个数
}
if(tmp == 0)//如果为0,直接下一次循环
continue;
if(num%tmp == 0 ) {//如果可整除,美丽值结果+1
res++;
}
}
return res;//返回结果
}
};
第七题: 1984. 学生分数的最小差值 - 力扣(LeetCode)

如果是在没有思路,那不妨先让其有序。

class Solution {
public:
int minimumDifference(vector& nums, int k) {
int ret=INT_MAX;
int n=nums.size();
sort(nums.begin(),nums.end());
for(int left=0,right=0;right<n;right++)
{
if(right-left+1==k)
{
ret=min(ret,(nums[right]-nums[left++]));
}
}
return ret;
}
};
没有解决的题目:

会员题除外

  1. 统计完全子字符串 - 力扣(LeetCode)

  2. 使二进制字符串字符交替的最少反转次数 - 力扣(LeetCode)

  3. 存在重复元素 III - 力扣(LeetCode)

目录
相关文章
|
传感器 物联网 数据处理
认识IoT的基本概念和架构
物联网(Internet of Things, IoT)是现代信息技术的重要组成部分,通过将物理设备连接到互联网,实现设备之间的互联和数据交换。随着传感技术、通信技术和数据处理能力的不断提升,物联网在各个领域展现出巨大的潜力和应用前景。本文将介绍物联网的基本概念、架构、关键技术及其应用场景,并探讨其未来的发展趋势。
3588 3
|
机器人 BI vr&ar
伙伴客户案例|阿里云RPA助力制造零售企业降本增效 ——财务场景篇
RPA全称机器人流程自动化(Robotic Process Automation),是一种新兴的“数字劳动力”,可以替代或辅助人完成规则明确的重复性劳动,大幅提升业务流程效率,实现企业业务流程的自动化和智能化,从而降本增效。目前,RPA解决方案的应用场景几乎涵盖了所有行业,包括银行、保险、制造、零售、医疗、物流、电子商务甚至政府和公共机构。
3562 3
伙伴客户案例|阿里云RPA助力制造零售企业降本增效 ——财务场景篇
|
5月前
|
人工智能 JSON 文字识别
一行命令,让你的 Code Agent 会读PDF
一行命令 `npx skills add tanis90/pdf-converter-mineru`,即可为Claude Code、Cursor等主流Code Agent注入PDF阅读能力。基于上海AI Lab开源的MinerU引擎,支持扫描件OCR、表格/公式识别、中英混排,自动选择快读或高精模式,开箱即用,无需部署MCP服务。(239字)
3387 16
|
人工智能 编解码 自然语言处理
VideoMind:Chain-of-LoRA突破时间盲区让AI真正看懂长视频
VideoMind是一种新型视频语言代理,专为解决长视频时间定位理解挑战设计。它通过“Chain-of-LoRA”技术结合四个专业角色(Planner、Grounder、Verifier、Answerer)实现高效推理。Planner分析查询并制定计划;Grounder精确定位视频时刻;Verifier验证候选时刻准确性;Answerer生成最终答案。此架构在14个公共基准上表现出色,尤其在长视频定位任务中超越了现有模型,同时保持高内存效率。VideoMind推动了多模态AI的发展,提供了解决复杂视频理解问题的新方法。
11129 5
|
自然语言处理 监控 安全
2025年阿里云短信验证码价格多少钱?计费模式与场景选型指南
随着企业数字化转型,短信验证码作为用户身份验证的重要工具,其成本与效率的平衡至关重要。阿里云短信服务以高可靠性、灵活计费和多场景适配著称。按量付费模式适合需求波动大的场景,而短信套餐包则为长期稳定需求提供了成本优势。针对不同业务场景,如高频验证、跨境业务及中小型企业轻量级需求,阿里云提供了定制化的选型策略。此外,通过阶梯定价、防盗刷监控等措施实现成本优化与风险规避,并不断进行技术升级以确保服务的安全性和稳定性。根据2025年最新数据,企业可根据自身需求选择最适合的阿里云短信验证码服务方案。
|
传感器 机器学习/深度学习 人工智能
智能电网巡检与传感器数据AI自动分析
智能电网设备巡检与传感器数据分析利用AI技术实现自动化分析和预警。通过信息抽取、OCR技术和机器学习,系统可高效处理巡检报告和实时数据,生成精准报告并提供故障预判和早期识别。AI系统24小时监控设备状态,实时发出异常警报,确保设备正常运行,提升运维效率和可靠性。
990 6
|
Java Unix
Sun Microsystems
Sun Microsystems
891 62
|
JavaScript Java Android开发
kotlin安卓在Jetpack Compose 框架下跨组件通讯EventBus
**EventBus** 是一个Android事件总线库,简化组件间通信。要使用它,首先在Gradle中添加依赖`implementation &#39;org.greenrobot:eventbus:3.3.1&#39;`。然后,可选地定义事件类如`MessageEvent`。在活动或Fragment的`onCreate`中注册订阅者,在`onDestroy`中反注册。通过`@Subscribe`注解方法处理事件,如`onMessageEvent`。发送事件使用`EventBus.getDefault().post()`。
|
监控 测试技术 持续交付
掌握跨平台测试策略:确保应用的无缝体验
【10月更文挑战第14天】在多元化设备和操作系统的今天,跨平台测试策略成为确保应用质量和性能的关键。本文探讨了跨平台测试的重要性、核心优势及实施步骤,涵盖Web、移动和桌面应用的测试方法,帮助开发者提高应用的无缝体验。
|
机器学习/深度学习 Dart 算法
机器学习实战 | LightGBM建模应用详解
本篇详细讲解LightGBM的工程应用方法。LightGBM是微软开发的boosting集成模型,和XGBoost一样是对GBDT的优化和高效实现,但它很多方面比XGBoost有着更为优秀的表现。
10738 105
机器学习实战 | LightGBM建模应用详解

热门文章

最新文章