题意:
一个长度为 n 的字符串 s,其中仅包含 'Q', 'W', 'E', 'R' 四种字符。
如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。
现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
如果 s 已经平衡则输出0。
Input
一行字符表示给定的字符串s
Output
一个整数表示答案
Examples
Input
QWER
Output
0
Input
QQWE
Output
1
Input
QQQW
Output
2
Input
QQQQ
Output
3
Note
1<=n<=10^5
n是4的倍数
字符串中仅包含字符 'Q', 'W', 'E' 和 'R'.
我的题解:
本题利用尺取法求最小长度。
尺取做法: 循环遍历字符串中每种字符串个数,求最小子串长度,如果当前区间替换后可以平衡,将区间左端点右移动,否则右端点右移。
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<string>
5 #include<string.h>
6 #include<map>
7 using namespace std;
8 char ch[]={'Q','W','E','R'};
9 int a[4] = { 0 }; //词频
10 int b[4] = { 0 };
11 int main(){
12 string str;
13 cin>>str;
14 //scanf("%s",str[0]);
15 int lens=str.length();
16 int replace=str.length();
17 for(int i=0;i<lens;i++){
18 for(int j=0;j<4;j++){
19 if( str[i] == ch[j] )
20 {
21 a[j]++;
22 break;
23 }
24 }
25 }
26 //for(int i=0;i<4;i++)cout<<a[i]<<" ";
27 int l=0,r=-1;
28 while(r<lens){
29 for(int i=0;i<4;i++)
30 b[i]=a[i];
31
32 for(int i=l;i<=r;i++){
33 // for(int j=0;j<4;j++){
34 // if(str[i]==ch[j])
35 // {
36 // b[j]--;
37 // break;
38 // }
39 // }
40 if(str[i]==ch[0])
41 b[0]--;
42 else if(str[i]==ch[1])
43 b[1]--;
44 else if(str[i]==ch[2])
45 b[2]--;
46 else
47 b[3]--;
48 }
49 //for(int i=0;i<4;i++) cout<<b[i]<<" ";
50
51 int m=max(max(b[0],b[1]),max(b[2],b[3])); //max
52
53 // for(int i=1;i<4;i++)
54 // if(max<b[i])
55 // max=b[i];
56 //
57 int nums=r-l+1-(4*m-b[0]-b[1]-b[2]-b[3]);
58
59 if(nums>=0 && nums%4 == 0){
60 replace = min (replace , r-l+1);
61 if(replace) l++; //后面指针后移
62 else break;
63 }else{
64 r++; // 前面指针后移
65 }
66 }
67 //printf("%d\n",replace);
68 cout<<replace<<endl;
69 return 0;
70 }
在情况较少情况下尽量用if else 速度比for循环快! 用for循环超时了 orz....