https://leetcode-cn.com/problems/replace-the-substring-for-balanced-string/
滑动窗口+判定。对于窗口大小为len。窗口外的每个字母出现次数小于等于n/4时候,一定可以替换成功,这时就可以尝试更小的窗口。对于窗口大小的选择,我刚开始用二分,O(nlgn)的复杂度,结果 n=10^5 会超时。后来发现双指针就可以O(n)就过了。
二分:
class Solution {
public:
char chs[4] = {'Q', 'W', 'E', 'R'};
unordered_map<char, int> cnt;
bool judge(string s, int len)
{
int n = s.length();
for(int i = 0; i + len - 1 < n; i++)
{
unordered_map<char, int> tmp = cnt;
for(int j = i; j < i + len; j++)
tmp[s[j]]--;
int need = 0;
for(int j = 0; j < 4; j++)
{
if(tmp[chs[j]] > n / 4) need = n;
else need += n / 4 - tmp[chs[j]];
}
if(len >= need) return true;
}
return false;
}
int balancedString(string s) {
int n = s.length();
int l = 0, r = n;
for(char ch : s)
cnt[ch] ++;
while(l < r)
{
int mid = l + r >> 1;
if(judge(s, mid)) r = mid;
else l = mid + 1;
}
return l;
}
};
双指针:
class Solution {
public:
int balancedString(string s) {
unordered_map<char, int> cnt;
for(char ch : s)
cnt[ch]++;
int l = 0, r = 0;
int n = s.length(), need = n / 4;
int res = n;
while(r <= n)
{
if(cnt['Q'] > need || cnt['W'] > need || cnt['E'] > need || cnt['R'] > need)
{
cnt[s[r++]]--;
continue;
}
res = min(res, r - l);
if(res == 0) break;
cnt[s[l++]]++;
}
return res;
}
};