送给大家一句话:
在最黑暗的那段人生,是我自己把自己拉出深渊。没有那个人,我就做那个人。——中岛美嘉
滑动窗口进阶
前言
继续学习滑动窗口问题。
入门篇我们了解滑动窗口的原理和算法思路:
- 双指针如果同方向移动即可使用滑动窗口
- 滑动窗口的原理是数组的单调性
- 基本步骤:进窗口-判断-出窗口-更新结果
接下来我们继续巩固我们的算法思维。来看三道题目:
Leetcode 1658. 将 x 减到 0 的最小操作数
上连接 !!!1658. 将 x 减到 0 的最小操作数
题目描述
根据描述,就是从左右两边分别取数,直到x减到零。来看一个样例:
- 输入:nums = [3,2,20,1,1,3], x = 10
- 输出:5
- 解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。
算法思路
来看最最最直接的算法:暴力枚举!!!因为只能取两头的元素,所以等价于中间留下的值的和恰好等于数组和减去x。那这样遍历所有的子串,找到最小的即可!!!
怎么进行优化呢?当然是使用单调性来进行优化:
每次我们统计一个子串的和时,想一想right有必要回到 left++ 然后从新开始遍历吗?
当然不用!!!
因为left 到 right 就不满足要求(中间留下的值的和大于数组和减去x),left++后right从left开始最终也会回到原来位置,所以没有必要。
那这样就形成了滑动窗口:
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
//进窗口
//判断
//出窗口
//求和
int sum = 0;
for(auto s:nums) sum += s;
int tmp = 0;//中间量
int ans = INT_MAX;
//特殊情况处理
if(sum - x == 0) return nums.size();
if(sum - x < 0) return -1;
int n = nums.size();
for(int left = 0,right = 0;right < n;right++)
{
//进窗口
tmp += nums[right];
//判断
while(sum - x < tmp && left < right)
{
//出窗口
tmp -= nums[left];
//
left++;
}
//更新结果
if(sum - x == tmp) ans = min(ans,n - (right - left +1));
}
return ans == INT_MAX ? -1 : ans;
}
};
这样完美解决!!!
过啦!!!
Leetcode 904. 水果成篮
家人们 !跟上我们的节奏!!! 904. 水果成篮
题目描述
这道题很有意思奥(奇怪的农场主人…)
根据题目描述,我们需要找到一个子串中(只能有两种水果)的最大长度!来看一个样例:
- 输入:fruits = [3,3,3,1,2,1,1,2,3,3,4]
- 输出:5
- 解释:可以采摘 [1,2,1,1,2] 这五棵树。只有两种水果并且最长!
算法思路
直接来最暴力的算法:暴力枚举。遍历所有的子串找到符合条件的最长字串即可(当然肯定会超时!!!)
那么怎么进行优化呢???(当然是滑动窗口)
每次找到不符合条件的子串,有没有必要将right指向left呢???
当然没有!!! 最长的已经遍历过,从头开始完全没有必要!!!
1,2,1,1,2,3
不和条件 就没有必要重新遍历2,1,1,2,3
这里的判断方法借助哈希算法来解决:
class Solution {
public:
int totalFruit(vector<int>& f) {
//进窗口
//判断
//出窗口
//更新答案
//用来统计水果种数
int hash[100001] = {
0} , ret = 0;
int n = f.size();
//滑动窗口
for(int left = 0,right = 0,kinds = 0 ; right < n;right++){
//进窗口
//如果哈希表中是0 那说明是新品种
if(hash[f[right]] == 0) kinds++;
hash[f[right]]++;
//判断
while(kinds > 2){
hash[f[left]]--;
//出窗口前要检查种类是否变化
if(hash[f[left]] == 0) kinds--;
left++;
}
//更新结果
ret = max(ret,right - left + 1);
}
return ret;
}
};
提交看一下:过啦!!!!!!!!!
Leetcode 438. 找到字符串中所有字母异位词
家人们!上车!!!438. 找到字符串中所有字母异位词
题目描述
这道题很有说法