題意:
有一個只含有 'Q', 'W', 'E', 'R'
四種字符,且長度為 n
的字符串。
假如在該字符串中,這四個字符都恰好出現 n/4
次,那么它就是一個「平衡字符串」。
給你一個這樣的字符串 s
,請通過「替換子串」的方式,使原字符串 s
變成一個「平衡字符串」。
你可以用和「待替換子串」長度相同的 任何 其他字符串來完成替換。
請返回待替換子串的最小可能長度。
如果原字符串自身就是一個平衡字符串,則返回 0
。
Example 1:
輸入:s = "QQQW"
輸出:2
解釋:我們可以把前面的 "QQ" 替換成 "ER"。
Example 2:
輸入:s = "QQQQ"
輸出:3
解釋:我們可以替換后 3 個 'Q',使 s = "QWER"。
思路:
從答案出發,目標是找出一個子串,替換它然后使得整個串中的四個字母的數量相同,假設最后的結果是替換子串s[i,j](表示s中從第i個字符到第j個字符組成的子串),下面我們要做的就是如何搜索出i和j的值,使得j-i盡可能小,首先想到的就是暴力求解,枚舉出所有的i和j,判斷是否滿足要求,在滿足要求的基礎上取最小值,時間復雜度O(n^2),超時是逃不了的,但是這里很容易想到解決辦法:二分搜索!,確定i,使用二分搜索j,時間復雜度O(nlogn),這樣就能AC了。

1 const int N=1e5+10; 2 class Solution { 3 public: 4 int sol(char c){ 5 if(c=='Q')return 0; 6 else if(c=='W')return 1; 7 else if(c=='E')return 2; 8 return 3; 9 } 10 int a[N][4]; 11 bool f[4]; 12 int balancedString(string s) { 13 int n=s.size(); 14 for(int i=0;i<n;i++){ 15 a[i+1][0]=a[i][0]; a[i+1][1]=a[i][1]; a[i+1][2]=a[i][2]; a[i+1][3]=a[i][3]; 16 if(s[i]=='Q')a[i+1][0]++; 17 else if(s[i]=='W')a[i+1][1]++; 18 else if(s[i]=='E')a[i+1][2]++; 19 else a[i+1][3]++; 20 } 21 int ans=0x3f3f3f3f; 22 for(int i=0;i<=n;i++){ 23 int l=i,r=n; 24 while(l<=r){ 25 int mid=(l+r)/2; 26 bool f=true; 27 for(int j=0;j<4;j++){ 28 if(a[i][j]+a[n][j]-a[mid][j]>n/4){f=false; break;} 29 } 30 if(f)r=mid-1; 31 else l=mid+1; 32 } 33 r++; 34 if(r!=n+1)ans=min(ans,r-i); 35 if(ans==0)return 0; 36 } 37 return ans; 38 } 39 };