• 平衡字符串


    题意:

    一个长度为 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
    ",replace);
    68     cout<<replace<<endl;    
    69     return 0;
    70 }

     在情况较少情况下尽量用if else 速度比for循环快!   用for循环超时了 orz....

    流转星云
  • 相关阅读:
    微软研究院的分布式云计算框架orleans
    DDDLite的权限管理
    OAuth在WebApi
    LVM pvcreate,vgcreate,lvcreate,mkfs
    List subList()的一个demo
    web 环境项目(intellj部署的tomcat) 重启时报 Exception in thread "HouseKeeper" java.lang.NullPointerException (转)
    Ehcache详细解读(转)
    Java 理论与实践: 正确使用 Volatile 变量(转)
    解决SecureCRT中文显示乱码
    免费动态域名解析
  • 原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/12624356.html
Copyright © 2020-2023  润新知