灵神算法题单——不定长滑动窗口(求最长最大)
1208. 尽可能使字符串相等
简单的滑动窗口三部曲:移入窗口、是否移出、更新结果。
算差值这里采用abs()函数来实现
class Solution {
public:
int equalSubstring(string s, string t, int maxCost) {
int l=s.size();
int ant=0,mi=INT_MIN;
for(int i=0,j=0;i<l;i++)
{
ant+=abs(s[i]-t[i]);
while(j<=i&&ant>maxCost)
{
ant-=abs(s[j]-t[j]);
j++;
}
mi=max(mi,i-j+1);
}
return mi;
}
};
2779. 数组的最大美丽值
先排序然后进行区间合并,也可看出是一种滑动窗口
class Solution {
public:
int maximumBeauty(vector<int>& nums, int k) {
int ma=INT_MIN;int ant=0;
sort(nums.begin(),nums.end());
int l=nums.size();
int r=nums[0]+k;
for(int i=0,j=0;i<l;i++)
{
ant++;
while(j<=i&&nums[i]-k>r)
{
j++;ant--;
r=nums[j]+k;
}
ma=max(ma,i-j+1);
}
return ma;
}
};
1658. 将 x 减到 0 的最小操作数
这道题可以理解为求窗口内值恰好为sum-x时窗口的最长值,当然经过转换变为未入窗口的最小值。
首先遍历一遍数组求出总和,算出差后面滑动窗口即可
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int sum=0;
for(auto i:nums)sum+=i;
if(x>sum)return -1;
int cha=sum-x;int l=nums.size();
int ant=0,mi=INT_MAX;
for(int i=0,j=0;i<l;i++)
{
ant+=nums[i];
while(j<=i&&ant>cha)
{
ant-=nums[j];
j++;
}
if(cha==ant)mi=min(mi,l-i+j-1);
}
return mi==INT_MAX?-1:mi;
}
};
1838. 最高频元素的频数
这个题也是与顺序无关所以我们先排序,假设窗口内都加到与nums[i]一样,如果k不够,则移动j
由于数值有点大,需要开long long
class Solution {
public:
int maxFrequency(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
long long ma=0;long long ant=0;
int l=nums.size();
for(long long i=0,j=0;i<l;i++)
{
ant+=i==0?0:(i-j)*(nums[i]-nums[i-1]);
while(j<=i&&ant>k)
{
ant-=nums[i]-nums[j];
j++;
}
ma=max(ma,i-j+1);
}
return ma;
}
};
2516. 每种字符至少取 K 个
跟上一题类似,转换为求窗口内每种字符最多取总数-k个,最后转换一下即可。
class Solution {
public:
int takeCharacters(string s, int k) {
int l =s.size();
int a[5]={0};
for(auto i:s)a[i-'a']++;
for(int i=0;i<3;i++)
{a[i]-=k;if(a[i]<0)return -1;}
int ma=0,ant=0;
for(int i=0,j=0;i<l;i++)
{
a[s[i]-'a']--;
while(j<=i&&a[s[i]-'a']<0)
{
a[s[j]-'a']++;
j++;
}
ma=max(ma,i-j+1);
}
return l-ma;
}
};
2271. 毯子覆盖的最多白色砖块数
贪心加滑动窗口加排序
class Solution {
public:
int maximumWhiteTiles(vector<vector<int>>& tiles, int carpetLen) {
sort(tiles.begin(),tiles.end());
int n=tiles.size();
int ant=0,ma=0;
for(int i=0,j=0;i<n;i++)
{
ant+=tiles[i][1]-tiles[i][0]+1;
while(j<=i&&tiles[i][1]-tiles[j][1]>=carpetLen)
{
ant-=tiles[j][1]-tiles[j][0]+1;
j++;
}
ma=max(ma,ant-max(0,tiles[i][1]-carpetLen+1-tiles[j][0]));
}
return ma;
}
};