[leetcode] Repeated DNA Sequences

Problem Description: 

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"].
刚拿到这个题目时,我的想法是,在一个字符串中寻找一些子串,KMP算法能够提高在一个字符串中寻找模式串的速度,所以是否可以用KMP算法呢?直观上来看,KMP算法需要一个模式串,在上面的题目中这个模式串可以是字符串s的任意长度为10的子串。枚举这些子串,再在s中寻找其他位置上是否还出现过该子串。这种方法应该是可行的,但是还是太暴力了。

另外一个想法是字典树。构造一个字典树来存储字符串s的所有长度为10的子串,由于这里只有4个字母,10层的话大概需要2700+个结点。我自认为可以接受,没想到最后还是"Memory Limit Exceeded"。

最后,参考了discuss才明白,这里只有4个字母可以两个bit来进行编码,这样一个长度为10的基因序列字符串(20位)可以用int(32位)来表示。另外当知道子串"s1s2...s10"对应的int数值为x,求“s2s3...s11”对应的int数值y时,可以先x与“1111 1111 1111 0011 1111 1111 1111 1111”进行&运算,即去掉了s1字母,然后将x左移两位,最后加上s11对应的编码,即得到y。因此,只需要遍历一遍字符串s,就可以求出它所有的长度为10的子串对应的编码值,将这些编码值存储到一个unordermap中,当某个值出现超过一次时即为所求的字符串(遍历时是知道子串的起始位置的)。


你可能感兴趣的:([leetcode] Repeated DNA Sequences)