LeetCode-187-重复的DNA序列
重复的DNA序列
题目描述:所有 DNA 都由一系列缩写为 'A','C','G' 和 'T' 的核苷酸组成,例如:"ACGAATTCCG"。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
示例说明请见LeetCode官网。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/repeated-dna-sequences/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解法一:哈希
首先,判断特殊情况,如果字符串的长度小于11,说明不够组成一个目标子串,不可能有重复的序列,直接返回空。
否则,初始化一个map,用来记录每一个不重复的长度为10的子串,key为子串,value表示相应的key是否是重复序列。然后遍历字符串,每10位作为一个子串,判断当前子串如果不存在,则添加到key中;如果存在且已标为重复,则跳过,如果没有标为重复,则标为重复子串。
最后,返回标为重复的子串即为重复的序列。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class LeetCode_187 {
/**
* 哈希
*
* @param s
* @return
*/
public static List<String> findRepeatedDnaSequences(String s) {
// 如果字符串的长度小于11,说明不够组成一个目标子串,不可能有重复的序列,直接返回空
if (s == null || s.length() < 11) {
return new ArrayList<>();
}
// 记录每一个不重复的长度为10的子串,key为子串,value表示相应的key是否是重复序列
Map<String, Boolean> map = new HashMap<>();
// 长度间隔为10,从第一个字符开始
int startIndex = 0, endIndex = startIndex + 10;
// 遍历到最后一个字符结束
while (endIndex <= s.length()) {
String substring = s.substring(startIndex, endIndex);
// 如果当前子串不存在,则添加到key中;如果存在且已标为重复,则跳过,如果没有标为重复,则标为重复子串
if (map.containsKey(substring)) {
if (!map.get(substring)) {
map.put(substring, true);
}
} else {
map.put(substring, false);
}
startIndex++;
endIndex++;
}
return map.entrySet().stream().filter(e -> e.getValue()).map(Map.Entry::getKey).collect(Collectors.toList());
}
public static void main(String[] args) {
// 测试用例,期望输出: ["AAAAACCCCC","CCCCCAAAAA"]
for (String str : findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT")) {
System.out.println(str);
}
}
}
【每日寄语】 星星之火,可以燎原。