前言
竟然足足一星期没刷题了,上周毕设紧急赶了波工,就没什么动力,希望不会因此生疏了,组会过后刷新了焦虑值,又是新的一周,干巴爹
209. 长度最小的子数组
- 暴力解法:时间复杂度O(n2),两个for循环,超时了没通过
-
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int num = 100010; // 累积长度 或 INT32_MAX int len = nums.size(); for(int i = 0; i < len ; i++){ int sum = 0; for(int j = i; j < len; j++){ sum += nums[j]; if(sum >= target){ if(j - i + 1< num){ num = j - i + 1; } break; } } } if(num == 100010) return 0; else return num; } };
-
- 滑动窗口:时间复杂度O(n),一个for循环,保证一个大于等于目标值的最大窗口去慢慢缩小
- 解决:窗口内是什么?如何移动窗口的起始位置?如何移动窗口的结束位置?
-
class Solution { public: int minSubArrayLen(int target, vector<int>& nums) { int num = INT32_MAX; // 结果 int sum = 0; // 滑动窗口数值之和 int i = 0; // 滑动窗口起始位置 for(int j = 0; j < nums.size(); j++){ sum += nums[j]; while(sum >= target){ // 保持窗口刚好大于target num = num < j - i + 1 ? num : j - i + 1; // 简洁写法 sum -= nums[i++]; } } // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列 return num == INT32_MAX ? 0 : num; } };
904. 水果成篮
- 官方题解注释版,进一步学习滑动窗口,并且熟悉容器哈希表的操作,这个更熟悉
-
class Solution { public: int totalFruit(vector& fruits){ int n = fruits.size(); unordered_map<int, int>count;//建立哈希表counts int i = 0;//窗口起始值 int ans = 0;//result返回值而已 for (int j = 0; j < n; j++){ count[fruits[j]]++;//往哈希表里存放尾部键fruits[j],值++ while (count.size() > 2){//防止两个键值以上,俩篮子 auto it = count.find(fruits[i]);//auto自动类型,迭代器it指向容器中的元素 --it->second;//it->second访问值,进行减减操作,it->first访问键 if (it->second == 0){//值=0,及时删掉该类别 count.erase(it);//抹掉这一类 } ++i;//左边界右移 } ans = max(ans, j - i + 1);//每次循环结束更新最大长度 } return ans;//返回result }
- 最小滑窗模板:在迭代右移左边界的过程中更新结果
-
while j < len(nums): 判断[i, j]是否满足条件 while 满足条件: 不断更新结果(注意在while内更新!) i += 1 (最大程度的压缩i,使得滑窗尽可能的小) j += 1
-
- 最大滑窗模板:在迭代右移右边界的过程中更新结果
-
while j < len(nums): 判断[i, j]是否满足条件 while 不满足条件: i += 1 (最保守的压缩i,一旦满足条件了就退出压缩i的过程,使得滑窗尽可能的大) 不断更新结果(注意在while外更新!) j += 1
-
后言
琢磨累了,明天再写比较难的字符串,感觉现在写不出的原因有两个,一个是思路不熟悉,一个是C++的操作忘掉了,慢慢来吧,干饭去咯