lc面试准备:Repeated DNA Sequences
1 题目
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"].
接口
public List<String> findRepeatedDnaSequences(String s);
2 思路
寻找重复出现1次以上的10个字符串。
思路1:TLE。从第一个子字符串开始遍历,并存储在List中,如果某个子字符串出现两次,就将其添加到结果List中。
思路2:映射4个字符'A''C''G''T'为整数,对整数进行移位以及位与操作,以获取相应的子字符串。
①将ACGT进行二进制编码
A -> 00
C -> 01
G -> 10
T -> 11
②在编码的情况下,每10位字符的组合是一个数字value,且10位的字符串有20位;int是32位,可以储存。例如
ACGTACGTAC -> 00011011000110110001
AAAAAAAAAA -> 00000000000000000000
采用HashSet来存储这些value。20位的二进制数,至多有2^20种组合,因此hash set的大小最大为2^20,即1024 * 1024。
每次向右移动1位字符,相当于字符串对应的int值左移2位,再将其最低2位置为新的字符的编码值,最后将高2位置0。
1 value = (value << 2) + 字符的编码值int; 2 value &= (1 << 20) - 1;//整数占32个位,获取其低20位(题中要求是长度为10的子字符串,映射为整数后,子字符串总共占用20位)
例如
src CAAAAAAAAAC
subStr CAAAAAAAAA
int 0100000000
subStr AAAAAAAAAC
int 0000000001
复杂度
3 代码
1 import java.util.HashMap; 2 import java.util.HashSet; 3 import java.util.LinkedList; 4 import java.util.List; 5 import java.util.Map; 6 import java.util.Set; 7 8 public class Solution { 9 // Time:O(n) Space:O(n) 10 private final static Map<Character, Integer> chsMap = new HashMap<Character, Integer>( 11 4); 12 static { 13 chsMap.put('A', 0); 14 chsMap.put('C', 1); 15 chsMap.put('G', 2); 16 chsMap.put('T', 3); 17 } 18 19 public List<String> findRepeatedDnaSequences(String s) { 20 Set<String> res = new HashSet<String>(); 21 final int length = s.length(); 22 if (length <= 10) 23 return new LinkedList<String>(res); 24 Set<Integer> intSet = new HashSet<Integer>(); 25 int value = 0; 26 for (int i = 0; i < 9; i++) { 27 value = (value << 2) + chsMap.get(s.charAt(i)); 28 } 29 for (int i = 9; i < length; i++) { 30 value = (value << 2) + chsMap.get(s.charAt(i)); 31 value &= (1 << 20) - 1; 32 if (intSet.contains(value)) { 33 res.add(s.substring(i - 9, i + 1)); 34 } 35 intSet.add(value); 36 } 37 return new LinkedList<String>(res); 38 } 39 }
4 扩展
- 当该字符串中没有出现长度为10的子字符串出现两次以上时,返回结果为[],而不是null。
- 若输入'AAAAAAAAAAA', 输出['AAAAAAAAAA']
5 参考
posted on 2015-04-07 22:08 BYRHuangQiang 阅读(321) 评论(0) 编辑 收藏 举报