每种字符至少取K个
2516. 每种字符至少取 K 个 - 力扣(LeetCode)
Solution
从两端取数字,根据之前的经验,直接用逆向思维,考虑中间的连续部分。
从两端取到每个字符各至少k个,先计算出原字符串中a,b,c的个数,如果有小于k的,直接返回-1.
从两端取至少k个,相当于从中间的连续部分取至多cnt_a-k,cnt_b-k,cnt_c-k个,这又回到了满足约束的连续子数组问题,用变长滑动窗口解决,记录最长窗口长度,最后用字符串总长度减去最大窗口长度就可以得到答案。
class Solution {
public:int takeCharacters(string s, int k) {vector<int> cnt(3, 0);int n = s.length();for (int i = 0; i < n; ++i) {cnt[s[i] - 'a']++;}int ans = -1;for (int i = 0; i < 3; ++i) {cnt[i] -= k;if (cnt[i] < 0)return -1;}for (int i = 0; i < 3; ++i)cout << cnt[i] << " ";vector<int> win_cnt(3, 0);int l = 0;for (int r = 0; r < n; ++r) {win_cnt[s[r] - 'a']++;while (win_cnt[s[r] - 'a'] > cnt[s[r] - 'a']) {win_cnt[s[l] - 'a']--;l++;}ans = max(ans, r - l + 1);}return n - ans;}bool check(vector<int>& a, vector<int>& b) {for (int i = 0; i < 3; ++i) {if (a[i] > b[i])return true;}return false;}
};