LeetCode 187. 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"].
问题分析
给定一个字符串S,代表一串DNA序列,找出长度为10,并且出现多次的子字符串。
给定的题目就是AAAAACCCCC出现了两次,*CCCCCAAAAA * 出现了两次。
比较容易能够想到用HashTabe,保存出现的所有的长度大于10的字串,记录他们出现的次数。最后返回符合要去的字符串(次数大于1)。只需要遍历一遍给定的字符串就可以了。中间认为Map的赋值和取值的操作为常数时间,那么时间复杂度就是O(n) ,空间复杂度是O(n)
虽然O(n)的空间复杂度已经不错了,但是所有的符合条件的字符串毕竟太多,有没有什么优化的可能呢。答案自然还是有的。题目给定的是DNA序列,对于DNA序列来说,只包含四种基本的碱基A,G,C,T,那么也就说明对于给定的字符串来说每一位都包含AGCT四种可能。就可以用00,01,10,11。也就是0,1,2,3这三个数字二进制格式进行代替。那么对于给定的字符串
AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT
可以表示为以下二进制形式(为了区分每一位,我用-分开了)
00-00-00-00-00-10-10-10-10-10-00-00-00-00-00-10-10-10-10-10-10-00-00-00-00-00-01-01-01-11-11-11
以上二进制字符就可以用数字类型进行表示,题目给定的位数是10,所以可以用int型进行表示。
所以说对于这道题来说,可以将String类型的HashTable 转化为Int型的HashTable,还是在已经程度上进行优化了的。
Java代码
public List<String> findRepeatedDnaSequences(String s) {
List<String> res = new ArrayList<>();
if(s==null||s.length()<10) return res;
int num =1;
int max = (int) Math.pow(2,20);// 2^20-1
for (int i = 0; i < 10; i++) {
num<<=2;
num|=convert2Int(s.charAt(i));
}
Map<Integer,Integer> map = new HashMap<>();
map.put(num,1);
for (int i = 10; i < s.length(); i++) {
num<<=2;
num&=(max-1);
num|=max;
num|=convert2Int(s.charAt(i));
int temp = 0;
if(map.containsKey(num)) temp = map.get(num);
map.put(num,temp+1);
}
for (int key:map.keySet()
) {
if(map.get(key)>1){
res.add(convert2Str(key));
}
}
return res;
}
String convert2Str(int num){
StringBuilder res = new StringBuilder();
while (num!=1){
switch (num&3){
case 0:
res.append('A');
break;
case 1:
res.append('C');
break;
case 2:
res.append('G');
break;
case 3:
res.append('T');
break;
}
num>>=2;
}
return res.reverse().toString();
}
int convert2Int(char c){
switch (c){
case 'A':
return 0;
case 'C':
return 1;
case 'G':
return 2;
case 'T':
return 3;
default:
return 0;
}
}
LeetCode学习笔记持续更新
GitHub地址 https://github.com/yanqinghe/leetcode
CSDN博客地址 http://blog.csdn.net/yanqinghe123/article/category/7176678