已解答
中等
相关标签
相关企业
提示
给你一个由字符 'a'
、'b'
、'c'
组成的字符串 s
和一个非负整数 k
。每分钟,你可以选择取走 s
最左侧 还是 最右侧 的那个字符。
你必须取走每种字符 至少 k
个,返回需要的 最少 分钟数;如果无法取到,则返回 -1
。
思路:
反向理解,既然题目要求从最左边和最右边取连续的一些数,不妨考虑在数组中取中间连续一段,符合条件:每个字符出现的次数要比该字符出现的总次数少大于等于k个。
因此,先经过一次循环,利用数组num记录a,b,c各自出现的次数。
然后,用一个数组nums,记录当前取得范围每个字母出现的次数,只要nums[i]<=num[i]-k,就表示可以继续插入,记录符合条件的最大长度
然后用双指针按照上述判断方法遍历就行。
最后总长度减去上述求出的最大长度就是最小取的次数。
需要注意每次放入新字符,需要先判断是否符合条件,再去算长度,先后次序不能颠倒。
class Solution {
public:
int takeCharacters(string s, int k) {
int ans=0;
int num[3]={0};
for(int i=0;i<s.size();i++)
{
num[s[i]-'a']++;
}
if(num[0]<k||num[1]<k||num[2]<k)
return -1;
int nums[3]={0};
for(int l=0,r=0;r<s.size();r++)
{
nums[s[r]-'a']++;
while(l<=r&&nums[0]>num[0]-k||nums[1]>num[1]-k||nums[2]>num[2]-k)
nums[s[l]-'a']--,l++;
ans=max(ans,r-l+1);//此时是满足的情况
}
return s.size()-ans;
}
};