一、Problem
有一個只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四種字符,且長度爲 n 的字符串。
假如在該字符串中,這四個字符都恰好出現 n/4 次,那麼它就是一個「平衡字符串」。
給你一個這樣的字符串 s,請通過「替換一個子串」的方式,使原字符串 s 變成一個「平衡字符串」。
你可以用和「待替換子串」長度相同的 任何 其他字符串來完成替換。
請返回待替換子串的最小可能長度。
如果原字符串自身就是一個平衡字符串,則返回 0。
輸入:s = "QWER"
輸出:0
解釋:s 已經是平衡的了。
提示:
1 <= s.length <= 10^5
s.length 是 4 的倍數
s 中只含有 ‘Q’, ‘W’, ‘E’, ‘R’ 四種字符
二、Solution
方法一:滑窗
- 窗口的含義
- 合法子串
- 窗口右邊界右移時機
- 每次都右移
- 窗口左邊界右移時機
- 窗口內部的字符都合法,這道題其實並不需要真的去替換字符,而是當一個子串從不合法變爲合法時,一定是將某些多餘的字符給隱式地替換了(
mp[c]--
),而給定的字符串的長度一定是 4 的倍數,所以保證可以替換成功。
- 窗口內部的字符都合法,這道題其實並不需要真的去替換字符,而是當一個子串從不合法變爲合法時,一定是將某些多餘的字符給隱式地替換了(
- 結算時機
- 左移前
class Solution {
boolean need(int[] mp, int tar) {
return mp['Q'] <= tar && mp['W'] <= tar && mp['E'] <= tar && mp['R'] <= tar;
}
public int balancedString(String S) {
int n = S.length(), tar = n >>> 2, l = 0, r = 0, ans = n+5, mp[] = new int[258];
char[] s = S.toCharArray();
for (char c : s)
mp[c]++;
while (r < n) {
mp[s[r]]--;
while (l < n && need(mp, tar)) {
mp[s[l]]++;
ans = Math.min(ans, r-l+1);
l++;
}
r++;
}
return ans;
}
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,