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

wordpress中下载按钮/正规优化公司哪家好

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.whsansanxincailiao.cn/news/32043990.html

相关文章:

  • 中国十大搜索引擎网站/企业网络推广的方法
  • 网站开发建设技术特点/免费收录网站提交
  • 网站建设图书推荐/广告seo是什么意思
  • 烟台哪个公司做网站好/2022年最火的新闻摘抄
  • 哪个网站容易做二级域名/网络推广网址
  • 西安网站建设/今日军事新闻最新消息新闻报道
  • 做新闻微网站有哪些方面/免费打广告平台有哪些
  • 做网站开发赚钱吗/市场调研一般怎么做
  • 音乐网站用什么语言做/关键词挖掘排名
  • wordpress 多重过滤/重庆做seo外包的
  • 企业网站建设多少钱/网络推广方案七步法
  • 有什么网站可以做java算法/百度一下app
  • python做网站的开发/短视频代运营方案策划书
  • 钱追得回吗/兰州seo外包公司
  • 如何做社交网站/指数网站
  • 湖南省住房和建设厅网站/南京最新消息今天
  • 揭阳市seo点击排名软件价格/seo的英文全称是什么
  • 如何拷贝网站代码/淘宝一个关键词要刷多久
  • 网站302跳转/免费网页制作网站
  • 咸阳北京网站建设/公司网站建设开发
  • 品牌网站建设 意义/线上营销活动案例
  • 便宜域名/成都seo经理
  • 怎么创建个人的网站/企业网站模板免费
  • 做网站一般用什么 语言/北京seo服务行者
  • 秘密花园app/网站排名优化公司哪家好
  • 展览中心网站建设/seo优化排名软件
  • 探测网站是什么程序做的/百度商店应用市场
  • 中国网站名/平台运营
  • 万象城网站建设/乔拓云建站平台
  • 江苏省政府门户网站建设/百度关键词查询网站