zoukankan      html  css  js  c++  java
  • HankerRank刷题第二天(string类型)

    今天做了两道string类型的题,第一道是比较简单的就不贴出来了

    第二道题:

    传送门:

    题目的大概意思是 给一个字符串S(由ACST四个字母组成),通过子串替换来使得S中ACST的个数相同,求得替换子串的最小长度

    如GAAATAAA,用GTTCC来替换AAATA即可变成GGTTCCAA符合条件,结果是5;

    题目最基本的思路是:从字符串中任意取出一个子串,只要剩下字串中ACST的个数都小于n/4即可。但如果有一个比n/4要大就不能通过替换成功。

    两个指针i和j,一个表示子串的开头一个表示子串的结尾。

    一开始想的是i从0-n,j从i-n;j每移动一次,保存ACST个数的数组相应减-,直到符合要求为止,结果=i-j+1,最小的结果即是题目结果。

    但是这样的时间复杂度是o(n*n),最终也超时了

    看了别人的代码,发现实在是太厉害了!

    先贴上核心代码:

    for(int i=0;i<n;i++)
            {
    
                while(j<n&&!isfinished())
                {
                    temp[m[s[j]]]--;
                    j++;
                }
                if(isfinished())
                {
                    int x=j-i;
                    if(result>x) result=x;
                }
                temp[m[s[i]]]++;
            }

    这样之后j不需要每一次都从i到n,而是只有一次o-n即可

    比如字符串GAAATAAA  初始: temp['G']=1 temp['A']=6 temp['T']=1

    第一次循环结束  temp['G']=0;temp['A']=2;temp['T']=0  i=0;j=6;

    然后不需要i=1,j=1重新,而是另temp[s[i]]++,也就是把之前去掉的子串头重新加入,j的值继续往后走

    第二次循环开始时:temp['G']=1;temp['A']=2;temp['T']=0  相当于去掉了从1到5的子串。

    全部代码:

    #include <iostream>
    #include <cstdio>
    #include <string>
    #include <map>
    
    using namespace std;
    
    
    int temp[4]={0};
    map<char,int> m;
    char s[500005];
    int n;
    
    bool isfinished()
    {
        for(int i=0;i<4;i++)
        {
            if(temp[i]>n/4)
                return false;
        }
        return true;
    }
    
    
    int main()
    {
        //freopen("a.txt","rw",stdin);
        int result=10000000;
        m['A']=0;
        m['C']=1;
        m['T']=2;
        m['G']=3;
        scanf("%d",&n);
        scanf("%s",&s);
        for(int i=0;i<n;i++)
        {
            temp[m[s[i]]]++;
        }
        if(isfinished())
        {
            printf("0
    ");
            return 0;
        }
        else{
            int j=0;
            for(int i=0;i<n;i++)
            {
    
                while(j<n&&!isfinished())
                {
                    temp[m[s[j]]]--;
                    j++;
                }
                if(isfinished())
                {
                    int x=j-i;
                    if(result>x) result=x;
                }
                temp[m[s[i]]]++;
            }
        }
        printf("%d
    ",result);
        return 0;
    }
  • 相关阅读:
    JUC强大的辅助类讲解--->>>CyclicBarrier(信号灯)
    JUC强大的辅助类讲解--->>>CyclicBarrier(循环栅栏)
    JUC强大的辅助类讲解--->>>CountDownLatchDemo (减少计数)
    FutureTask 概念及其相关使用
    集合不安全之 ---> Map
    集合不安全之 ---> Set
    180623-SpringBoot之logback配置文件
    180621-一个简单的时间窗口设计与实现
    180620-mysql之数据库导入导出
    180619-Yaml文件语法及读写小结
  • 原文地址:https://www.cnblogs.com/Qmelbourne/p/6735991.html
Copyright © 2011-2022 走看看