leetcode.每日一题.2516.每种字符至少取 K 个
给你一个由字符
'a'
、'b'
、'c'
组成的字符串s
和一个非负整数k
。每分钟,你可以选择取走s
最左侧 还是 最右侧 的那个字符。你必须取走每种字符 至少
k
个,返回需要的 最少 分钟数;如果无法取到,则返回-1
。
错误代码,不能从两边考虑,思路错误。
class Solution {
public:
int takeCharacters(string s, int k) {
if(k==0)return 0;
int n=s.length();
vector<int>idex;
int num[4];
memset(num,0,sizeof num);
for(int i=0;i<n;i++)
{
idex.push_back(++num[int(s[i]-'a')]);
}
// for(int i=0;i<n;i++)
// {
// cout<<idex[i]<<endl;
// }
for(int i=0;i<3;i++)
{
if(num[i]<k)return -1;
}
vector<bool>choose(n,0);
for(int i=0;i<n;i++)
{
if(idex[i]<=k)choose[i]=1;
}
int m=0;int maxM=0;
for(int i=0;i<n;i++)
{
if(choose[i]==0)
{
m+=1;
}
else if(choose[i]==1)
{
m=0;
}
maxM=max(maxM,m);
}
return n-maxM;
}
};
然后看了官方题解的双指针算法,有点思路了。
class Solution {
public:
int takeCharacters(string s, int k) {
vector<int> cnt(3, 0);
int len = s.size();
int ans = len;
for (int i = 0; i < len; i++) {
cnt[s[i] - 'a']++;
}
if (cnt[0] >= k && cnt[1] >= k && cnt[2] >= k) {
ans = min(ans, len);
} else {
return -1;
}
int l = 0;
for (int r = 0; r < len; r++) {
cnt[s[r] - 'a']--;
while (l < r && (cnt[0] < k || cnt[1] < k || cnt[2] < k)) {
cnt[s[l] - 'a']++;
l++;
}
if (cnt[0] >= k && cnt[1] >= k && cnt[2] >= k) {
ans = min(ans, len - (r - l + 1));
}
}
return ans;
}
};
作者:力扣官方题解
链接:https://leetcode.cn/problems/take-k-of-each-character-from-left-and-right/solutions/2928177/mei-chong-zi-fu-zhi-shao-qu-k-ge-by-leet-10ct/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
首次AC代码
class Solution {
public:
int takeCharacters(string s, int k) {
if(k==0)return 0;
int n=s.length();
int num[4];
memset(num,0,sizeof num);
for(int i=0;i<n;i++)
{
++num[int(s[i]-'a')];
}
for(int i=0;i<3;i++)
{
if(num[i]<k)return -1;
}
int l=-1;
int maxL=0;
for(int r=0;r<n;r++)
{
num[s[r]-'a']-=1;
while(l<r&&(num[0]<k||num[1]<k||num[2]<k))
{
l+=1;
num[s[l]-'a']+=1;
}
maxL=max(maxL,r-l);
}
return n-maxL;
}
};
今日完结撒花~