Repeated DNA Sequences

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

For example,

Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",

Return:
["AAAAACCCCC", "CCCCCAAAAA"].

 一、解法1:看到这个题目,立刻就想到了kmp模式匹配,然后就立刻开始写代码了,调试之后出现 Time Limit Exceeded!没有注意题目的特殊之处,习惯不好!

代码如下:

class Solution {
public:
     void getsubstr(const char*str1,int i,char*str2)
    {
        //assert(str1!=NULL&&str2!=NULL&&i>=0);
        for(int j=0;j<10;j++)
        {
            str2[j]=str1[i++];
        }
        str2[10]='\0';
    }
    void getnext(char*str,int* next)
    {
        int plen=strlen(str);
        int j=0,k=-1;
        next[0]=-1;
        while(j<plen-1)
        {
            if(k==-1||str[k]==str[j])
            {
                k++;j++;
                next[j]=k;
            }
            else
            {
                k=next[k];
            }
        }
    }
    bool str_kmp(const char*str1,int i,char*str2)
    {
        int len1=strlen(str1);
        int len2=strlen(str2);
        char* temp_str=new char[len1-i+1];
        int next[10]={0};
        
        getnext(str2,next);
        int j=0;
        for(;i<len1;i++)
        {
            temp_str[j++]=str1[i];
        }
        if(j<10) 
        {
            delete []temp_str;
            return false;
        }
        temp_str[j]='\0';
        
        int k=0;
        j=0;
        while(j<len1-i&&k<len2)
        {
            if(j==-1||temp_str[j]==str2[k])
            {
                j++;k++;
            }
            else
            {
                k=next[k];
            }
        }
        
        delete []temp_str;
        if(k==len2)
          return true;
         else
          return false;
    }
    
    vector<string> findRepeatedDnaSequences(string s) {
     const char* original_str=s.c_str();
     int str_len = strlen(original_str);
     char template_str[11];
     vector<string> str_vec;
     
     if(str_len<=10)
       return str_vec;
     for(int i=0;i<=str_len-10;i++)
     {
         getsubstr(original_str,i,template_str);
         if(str_kmp(original_str,i+1,template_str));
         {
             string temp=template_str;
             if(str_vec.end()==find(str_vec.begin(),str_vec.end(),temp))
             {
					str_vec.push_back(temp);
             }
             //str_vec.push_back(temp);
         }
     }
     return str_vec;
    }
   
};

 2.采用位操作的方法

class Solution {
public:
    int chartobit(char ch)
    {
        int bit=-1;
        switch(ch)
        {
            case 'A':
            bit=0;
            break;
            case 'C':
            bit=1;
            break;
            case 'G':
            bit=2;
            break;
            case 'T':
            bit=3;
            break;
        }
        return bit;
    }
    vector<string> findRepeatedDnaSequences(string s) {
        int cur=0;
        int len=s.length();
        int mask=0x3ffff;
        unordered_map<int,int> m;
        vector<string> vec;
        for(int i=0;i<9;i++)
        {
            cur=(cur<<2)|chartobit(s[i]);
        }
        for(int i=9;i<len;i++)
        {
            cur=((cur&mask)<<2)|chartobit(s[i]);
            if(m.find(cur)!=m.end())
            {
                if(m[cur]==1)
                {
                    vec.push_back(s.substr(i-9,10));
                    m[cur]++;
                }
            }
            else
            {
                m[cur]=1;
            }
        }
        return vec;
    }
   
};

 

posted @ 2015-03-21 15:25  zhanghui_dut  阅读(93)  评论(0)    收藏  举报