重复的DNA序列
所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG"。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来查找 DNA 分子中所有出现超多一次的10个字母长的序列(子串)。
示例:
输入: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出: ["AAAAACCCCC", "CCCCCAAAAA"]
思路:将字符串中所有长度为10的子串以及出现的次数用map保存,但是需要消耗很大的空间。
考虑到只有4中可能的字符A,C,G,T;可以对字符进行编码,用2bit来表示一个字符,一个含有10个字符的子串只要20bit就能表示,用一个int类型就能表示。
总长度为n的字符串,可能的子串共有n-9种,因此最多用n-9个int就能表示所有的字符组合。最坏的情况下,20bit共有2^20中组合,即1024*1024,
一个int类型4byte,因此额外消耗4MB的二外空间。
1 class Solution { 2 public ListfindRepeatedDnaSequences(String s) { 3 List list = new ArrayList (); 4 if(s.length() < 10) return list; 5 Map map = new HashMap (); 6 for(int i=10; i<=s.length(); i++) { 7 int result = 0; 8 for(int j=i-10, k=0; j) { 9 char c = s.charAt(j); 10 int num = 0; 11 switch(c) { 12 case 'A': num = 0; break; 13 case 'C': num = 1; break; 14 case 'G': num = 2; break; 15 case 'T': num = 3; break; 16 } 17 result += (num << 2*(9-k)); 18 } 19 if(map.containsKey(result) && map.get(result) == 0) { 20 list.add(s.substring(i-10, i)); 21 map.put(result, 1); 22 } else if(!map.containsKey(result)) 23 map.put(result, 0); 24 } 25 return list; 26 } 27 }