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

中国各大网站排名网站流量

中国各大网站排名,网站流量,wordpress自定义查询,网站空间 推荐滑动窗口:解决连续区间问题的黄金模板! 由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗⼝」的思想来解决这道题。 滑动窗口其实就是双指针的升级版,但此时这两个指针的移动方向是一致的 长度最小的子数组 题⽬链…

滑动窗口:解决连续区间问题的黄金模板!

由于此问题分析的对象是「⼀段连续的区间」,因此可以考虑「滑动窗⼝」的思想来解决这道题。

滑动窗口其实就是双指针的升级版,但此时这两个指针的移动方向是一致的

长度最小的子数组

题⽬链接:

长度最小的子数组

要点:

  • 寻找连续子数组使其和 ≥ target
  • 滑动窗口维护当前窗口和,动态调整左右边界

老师代码:

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

老师思路:

  1. 由于此问题分析的对象是**「⼀段连续的区间」,因此可以考虑「滑动窗⼝」**的思想来解决这道题。

    让滑动窗⼝满⾜:从 i 位置开始,窗⼝内所有元素的和⼩于 target (那么当窗⼝内元素之和第⼀次⼤于等于⽬标值的时候,就是 i 位置开始,满⾜条件的最⼩⻓度)。 做法:将右端元素划⼊窗⼝中,统计出此时窗⼝内元素的和

  2. 如果窗⼝内元素之和⼤于等于 target :更新结果,并且将左端元素划出去的同时继续判断是否满⾜条件并更新结果(因为左端元素可能很⼩,划出去之后依旧满⾜条件),如果窗⼝内元素之和不满⾜条件: right++ ,另下⼀个元素进⼊窗⼝

我的代码:

class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int ret = 0, sum = 0;int left = 0, right = 0;//第一次情况sum += nums[right];while(sum < target){right++;if(right >= nums.size()) return 0;//边界问题sum += nums[right];}ret = right - left + 1;while(right < nums.size()){while(sum >= target){ret = right - left + 1 < ret ? right - left + 1 : ret;sum -= nums[left++];}right++;if(right < nums.size()) sum += nums[right];}return ret;}
};

我的思路:

  1. 初始化左右指针left=0, right=0,窗口和sum=0
  2. right右移扩大窗口,累加元素值到sum
  3. sum ≥ target时,记录窗口长度,并尝试左移left缩小窗口
  4. 最终返回最小窗口长度

我的笔记:

  1. len(ret)最开始时不能定义成0,要不然没有比0更小的数组了,老师的想法就是len = INT_MAX,我的想法就是先找到第一个满足条件的子数组,把这个数组的长度作为ret的初始值

  2. 这个数组的所有元素都是正整数,因此right++,sum += nums[right] 的值一定是增加的,left–,sum -= nums[left]的值一定是减小的,因此可以使用滑动窗口来解决

  3. 下标每一次变化,如果要使用下标对应的元素,都要判断一下边界问题

  4. 先找到第一个满足条件的窗口,作为初始结果

  5. 所有元素为正数,保证窗口和单调性,适合滑动窗口

  6. 边界处理:当数组总和小于target时返回0

无重复字符的最长子串

题⽬链接:

无重复字符的最长子串

要点:

  • 寻找不含重复字符的最长连续子串
  • 哈希表记录字符最后一次出现的位置

老师代码:

class Solution
{public:int lengthOfLongestSubstring(string s){int hash[128] = { 0 }; // 使⽤数组来模拟哈希表int left = 0, right = 0, n = s.size();int ret = 0;while(right < n){hash[s[right]]++; // 进⼊窗⼝while(hash[s[right]] > 1) // 判断hash[s[left++]]--; // 出窗⼝ret = max(ret, right - left + 1); // 更新结果right++; // 让下⼀个元素进⼊窗⼝}return ret;}
};

老师思路:

  • 研究的对象依旧是⼀段连续的区间,因此继续使⽤「滑动窗⼝」思想来优化。

  • 让滑动窗⼝满⾜:窗⼝内所有元素都是不重复的。

  • 做法:右端元素 ch 进⼊窗⼝的时候,哈希表统计这个字符的频次:

    ▪ 如果这个字符出现的频次超过 1 ,说明窗⼝内有重复元素,那么就从左侧开始划出窗⼝,直到 ch 这个元素的频次变为 1 ,然后再更新结果。

    ▪ 如果没有超过 1 ,说明当前窗⼝没有重复元素,可以直接更新结果

image-20250222125530474

我的代码:

class Solution {
public:int lengthOfLongestSubstring(string s) {int arr[128] = {0};//相当于状态寄存器int left = 0, right = 0, ret = 0;while(right < s.size() ){if(arr[(int)s[right]] == 0)//如果这个字符没有出现过{arr[(int)s[right]]++;//对应标志位置1right++;//进窗口}else//如果出现过,开始出窗口{while(left < right && s[left] != s[right])//循环删除{arr[(int)s[left]] = 0;//标志位重新置0left++;//出窗口}//到了相等的位置,出窗口arr[(int)s[left]] = 0;//标志位重新置0left++;//出窗口}//更新结果ret = max(ret, right - left);}return ret;}};

我的思路:

  1. 使用数组hash[128]模拟哈希表,记录字符是否在窗口内
  2. right右移时检查字符是否重复
  3. 若重复,移动left到重复字符的下一个位置,并更新哈希表

我的笔记:

  1. 哈希表直接存储字符的存在状态,时间复杂度O(n)
  2. 左指针跳跃式移动,避免无效检查
  3. 关键代码:ret = max(ret, right - left)
最大连续1的个数

题⽬链接:

最大连续1的个数

要点:

  • 允许翻转k个0为1,求最长连续1子数组
  • 将问题转化为“窗口内0的个数不超过k”

老师代码:

class Solution
{
public:int longestOnes(vector<int>& nums, int k){int ret = 0;for(int left = 0, right = 0, zero = 0; right < nums.size(); right++){if(nums[right] == 0) zero++; // 进窗⼝while(zero > k) // 判断if(nums[left++] == 0) zero--; // 出窗⼝ret = max(ret, right - left + 1); // 更新结果}return ret;}
}

老师思路:

不要去想怎么翻转,不要把问题想的很复杂,这道题的结果⽆⾮就是⼀段连续的 1 中间塞了 k 个 0 嘛。 因此,我们可以把问题转化成:求数组中⼀段最⻓的连续区间,要求这段区间内 0 的个数不超过 k 个。

我的代码:

class Solution {
public:int longestOnes(vector<int>& nums, int k) {int num = 0, left = 0, right = 0;//right是下一个要判断的数字int ret = 0;while(right < nums.size()){if(nums[right] == 0)//如果为0,判断是否还有翻转名额{if(num >= k)//没有翻转名额{//出窗口while(left < right && nums[left] != 0) left++;//left找到最近的0位置left++;//left来到最近的0位置的后一个位置num--;//释放一个名额}else//名额还有{//进窗口num++;right++;}}else//如果为1{//进窗口right++;}//更新结果ret = max(ret, right - left);}return ret;}
};

我的思路:

  1. 维护窗口内0的计数zero
  2. zero > k时,左移left直到zero ≤ k
  3. 窗口大小即为当前有效区间长度

我的笔记:

  1. 贪心思想:尽可能保留更多1,通过翻转0扩展窗口
  2. 时间复杂度O(n),空间复杂度O(1)
  3. 关键优化:直接统计0的个数,避免复杂逻辑
将x减到0的最小操作数

题⽬链接:

将x减到0的最小操作数

要点:

  • 从数组两端删除元素,使得删除总和等于x
  • 转化为寻找中间连续子数组,其和等于total_sum - x

老师代码:

class Solution
{
public:int minOperations(vector<int>& nums, int x){int sum = 0;for(int a : nums) sum += a;int target = sum - x;// 细节问题if(target < 0) return -1;int ret = -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;else return nums.size() - ret;}
}

老师思路:

题⽬要求的是数组「左端+右端」两段连续的、和为 x 的最短数组,信息量稍微多⼀些,不易理清思路;我们可以转化成求数组内⼀段连续的、和为 sum(nums) - x 的最⻓数组。此时,就是熟悉的「滑动窗⼝」问题了。

我的代码:

class Solution {
public:int minOperations(vector<int>& nums, int x) {//求目标值int target = 0;for(int i = 0; i < nums.size(); i++){target += nums[i];}target -= x;//计算int left = 0, right = 0, sum = 0, ret = -1;while(right < nums.size()){//进窗口sum += nums[right++];while(left < right && sum > target)//判断是否要出窗口{//出窗口sum -= nums[left];left++;}//结果更新判断if(sum == target){ret = max(ret, right - left);}}if(ret == -1) return -1;else return nums.size() - ret;}
};

第二版

class Solution {
private:vector<int> ret;public:vector<int> findAnagrams(string s, string p) {int hash1[26] = { 0 };for(auto e : p) hash1[e - 'a']++;int hash2[26] = { 0 };int left = 0, right = 0, count = 0;while(right < s.size()){hash2[s[right] - 'a']++;if(hash2[s[right] - 'a'] <= hash1[s[right] - 'a']) count++;//维护count//这里不需要while循环,因为窗口大小是固定的,如果进入if语句只能是大了一个数if(right - left + 1 > p.size()){if(hash2[s[left] - 'a'] <= hash1[s[left] - 'a']) count--;hash2[s[left] - 'a']--;left++;}if(count == p.size()) ret.push_back(left);right++;} return ret;}
};

我的思路:

  1. 计算目标值target = sum(nums) - x
  2. 滑动窗口寻找和为target的最长子数组
  3. 最小操作数为总长度 - 最长子数组长度

我的笔记:

  1. 虽然题目中没有说这个数组的数都是正整数,但我们可以从题目下面的提示可以看到,其实这个数组的数都是正整数,因此我们就会想到单调性;又由于相当于找连续子数组,所以就可以用滑动窗口的方法

    做题时一定要看完题目

  2. 正难则反:如果一个问题从正面难解决,我们就可以反过来看一下

  3. 逆向思维:将两端删除问题转化为中间子数组问题

  4. 边界处理:当target < 0时直接返回-1

  5. 关键代码:ret = max(ret, right - left)

找到字符串中所有字母异位词

题⽬链接:

找到字符串中所有字母异位词

要点:

  • 寻找s中包含p所有字符排列的子串
  • 固定窗口大小为p的长度,维护字符频率表

老师代码:(没怎么听懂)

class Solution
{
public:vector<int> findAnagrams(string s, string p){vector<int> ret;int hash1[26] = { 0 }; // 统计字符串 p 中每个字符出现的个数for(auto ch : p) hash1[ch - 'a']++;													//注意int hash2[26] = { 0 }; // 统计窗⼝⾥⾯的每⼀个字符出现的个数int m = p.size();for(int left = 0, right = 0, count = 0; right < s.size(); right++)//count用于计算滑动窗口中的元素个数{char in = s[right];// 进窗⼝ + 维护 countif(++hash2[in - 'a'] <= hash1[in - 'a']) count++;if(right - left + 1 > m) // 判断{char out = s[left++];// 出窗⼝ + 维护 countif(hash2[out - 'a']-- <= hash1[out - 'a']) count--;}// 更新结果if(count == m) ret.push_back(left);//当滑动窗口的元素个数与p元素个数一致时}return ret;}
}

老师思路:老师的方法

  • 因为字符串 p 的异位词的⻓度⼀定与字符串 p 的⻓度相同,所以我们可以在字符串 s 中构造⼀个⻓度为与字符串 p 的⻓度相同的滑动窗⼝,并在滑动中维护窗⼝中每种字⺟的数量
  • 当窗⼝中每种字⺟的数量与字符串 p 中每种字⺟的数量相同时,则说明当前窗⼝为字符串 p 的异位词
  • 因此可以⽤两个⼤⼩为 26 的数组来模拟哈希表,⼀个来保存 s 中的⼦串每个字符出现的个数,另⼀个来保存 p 中每⼀个字符出现的个数。这样就能判断两个串是否是异位词。
  • 在更新结果时我们需要比较两个哈希表是否相同,可以用我的代码中的硬比较方法(遍历),但那种方法不能应对哈希表比较长的情况,老师的方法是利用count来统计窗口中有效字符个数,如果有效字符个数与p元素个数一致时 这里我不好描述,一定要去看视频

我的代码:

class Solution {
private:vector<int> ret;public://用于比较两个数组是否相同bool compare(int* arrs, int* arrp){for(int i = 0; i < 26; i++){if(arrp[i] != arrs[i]){return false;}}return true;}//用于判断是否应该执行出窗口bool compare2(int* arrs, int* arrp){for(int i = 0; i < 26; i++){//如果p中没有但s中有,或s中的某个字符多余p中的数量//返回真,执行出窗口if((arrp[i] == 0 && arrs[i] != 0) ||arrp[i] < arrs[i]){return true;}}return false;}vector<int> findAnagrams(string s, string p) {int arrp[26] = { 0 };int arrs[26] = { 0 };for(int i = 0; i < p.size(); i++){arrp[p[i] - 'a']++;}int left = 0, right = 0;while(right < s.size()){arrs[s[right++] - 'a']++;//进窗口while(left < right && compare2(arrs, arrp))//判断出窗口条件{arrs[s[left++] - 'a']--;//出窗口}if(compare(arrs, arrp))//判断更新结果的条件{ret.push_back(left);}}return ret;}
};

我的思路:

  1. 用哈希表hash1记录p的字符频率
  2. 滑动窗口维护hash2记录当前窗口字符频率
  3. 通过count变量统计有效字符个数,避免全表比较

我的笔记:

  1. 一定要注意字符串中的字符的ASCII码表对应的数组下标的值,对于数组下标要减去一个’a’才是从0开始的对应位置
  2. 我的思路是利用滑动窗口,每进窗口一个字符判断一下两个数组(哈希表)的元素关系,------硬比较
    • 如果p中没有而s中有,则s的滑动窗口中进入了p中没有的字母,我们需要出窗口
    • 如果arrs[i] > arrp[i] 则说明i这个位置的字母多了,我们需要出窗口,
    • 当这两个数组的元素个数一致时说明找到了,就返回left;
  3. 老师的方法更容易理解一些,因为这次的窗口大小是固定的 要学会利用这个特性
  4. 固定窗口大小:right - left + 1 == p.size()
  5. 哈希表优化:仅当字符频率匹配时更新count
  6. 关键代码:if(++hash2[in] <= hash1[in]) count++

注意事项总结

C++语法相关

  1. 数组初始化:int hash[128] = {0}需显式初始化
  2. 字符处理:s[right] - 'a'将字符映射到0-25的索引
  3. 边界检查:right < nums.size()避免越界

算法思路相关

  1. 单调性利用:元素为正数时,窗口和具有单调性,适合滑动窗口
  2. 逆向思维:如“将x减到0”转化为求中间子数组问题
  3. 哈希表优化:用count替代全表比较,时间复杂度从O(26n)降至O(n)
  4. 固定窗口:处理异位词时,窗口大小固定为p的长度,简化逻辑
  5. 去重技巧:通过跳跃移动左指针(如无重复字符问题),减少无效计算

位置的字母多了,我们需要出窗口,

  • 当这两个数组的元素个数一致时说明找到了,就返回left;
  1. 老师的方法更容易理解一些,因为这次的窗口大小是固定的 要学会利用这个特性
  2. 固定窗口大小:right - left + 1 == p.size()
  3. 哈希表优化:仅当字符频率匹配时更新count
  4. 关键代码:if(++hash2[in] <= hash1[in]) count++

注意事项总结

C++语法相关

  1. 数组初始化:int hash[128] = {0}需显式初始化
  2. 字符处理:s[right] - 'a'将字符映射到0-25的索引
  3. 边界检查:right < nums.size()避免越界

算法思路相关

  1. 单调性利用:元素为正数时,窗口和具有单调性,适合滑动窗口
  2. 逆向思维:如“将x减到0”转化为求中间子数组问题
  3. 哈希表优化:用count替代全表比较,时间复杂度从O(26n)降至O(n)
  4. 固定窗口:处理异位词时,窗口大小固定为p的长度,简化逻辑
  5. 去重技巧:通过跳跃移动左指针(如无重复字符问题),减少无效计算
http://www.dtcms.com/wzjs/308901.html

相关文章:

  • 公司互联网站全面改版怎么开通百度推广账号
  • 网站支付怎么做安全吗微营销系统
  • 交友网站去哪里做百度seo排名
  • 做网站用什么笔记本电子报刊的传播媒体是什么
  • 福州 网站设计公司app软件开发
  • 专门搜索知乎内容的搜索引擎郑州网站seo优化公司
  • wordpress修改模版seo入门书籍
  • 在哪里可以找到网站网络营销策划书的结构
  • 户县规划建设和住房保障局网站网络关键词优化方法
  • 中国工业品网北京自动seo
  • 安阳市设计网络优化器免费
  • 重庆网站制作的网站营销策划推广公司
  • 菏泽做网站的2024北京又开始核酸了吗今天
  • 设计君网站百度旗下的所有产品
  • 网站所有人网络宣传怎么做
  • 博天网站建设网络网站开发工具
  • 建一个网站需要什么流程企业产品营销策划推广
  • 做网站用的软件是什么了seo分析及优化建议
  • 网站开发的技术手段有哪些百度问答官网
  • 全国高校校园网站建设与发展高级研修班关键词优化排名要多少钱
  • 局域网网站制作线上营销活动有哪些
  • dedecms游戏门户网站源码seo课程培训班费用
  • 南昌模板建站公司关键词代做排名推广
  • 免费应用软件下载长春百度快速优化
  • 营销型网站建设中坚站百度的营销策略
  • 做介绍自己的短视频网站文娱热搜榜
  • 网站建设哪种品牌好代做seo排名
  • 内蒙古app开发公司网站seo诊断报告怎么写
  • 漳州市建设网站线上广告宣传方式有哪些
  • 自己做网站平台上海职业技能培训机构