DNA序列由一系列核苷酸组成,缩写为'A','C','G'和'T'。
例如,"ACGAATTCCG"是一个 DNA序列 。
在研究 DNA 时,识别 DNA 中的重复序列非常有用。
给定一个表示 DNA序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的长度为10的序列(子字符串)。你可以按 任意顺序 返回答案。
示例 1:
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC","CCCCCAAAAA"]
这是一道字符串处理题,由于使用java语言,字符处理直接使用内置函数。
基本思路:
代码实现如下:
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- class Solution1 {
- public List
findRepeatedDnaSequences(String s) { -
- Map
map = new HashMap<>(); - for (int i = 0; i <= s.length() - 10; i++) {
- String v = s.substring(i, i + 10);
- int count = map.getOrDefault(v, 0);
- map.put(v, ++count);
- }
- List
res = new ArrayList<>(map.size()); -
- for (Map.Entry
entry : map.entrySet()) { - if (entry.getValue() > 1) {
- res.add(entry.getKey());
- }
- }
- return res;
- }
-
- public static void main(String[] args) {
- Solution1 solution = new Solution1();
- System.out.println(solution.findRepeatedDnaSequences("AAAAAAAAAAAAA"));
- }
- }
这里直接使用2个HashSet优化,思路如下(set用于记录出现次数、res用于结果去重):
-
- import java.util.*;
-
- class Solution {
-
- public List
findRepeatedDnaSequences(String s) { - if (s.length() <= 10) {
- return new ArrayList<>();
- }
-
- Set
set = new HashSet<>(s.length() - 10); - Set
res = new HashSet<>(); -
- for (int i = 0; i <= s.length() - 10; i++) {
- String subString = s.substring(i, i + 10);
- if (!set.add(subString)) {
- res.add(subString);
- }
- }
- return new ArrayList<>(res);
- }
-
- public static void main(String[] args) {
- Solution solution = new Solution();
- System.out.println(solution.findRepeatedDnaSequences("AAAAAAAAAAAAA"));
- System.out.println(solution.findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"));
- }
- }
这块参考了其他人的解法,核心思路就是把字符串比较切换成数字比较:
按照上述思路代码实现:
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- class Solution3 {
-
- // 10个字符
- int N = 10;
- // 20位
- int FF = ((1 << 20) - 1);
-
- public List
findRepeatedDnaSequences(String s) { - if (s.length() <= N) {
- return new ArrayList<>();
- }
-
- Map
map = new HashMap<>(); - map.put('A', 0);
- map.put('C', 1);
- map.put('G', 2);
- map.put('T', 3);
-
- int x = 0;
- for (int i = 0; i < N; i++) {
- x = ((x << 2) | map.get(s.charAt(i)));
- }
-
- Map
countMap = new HashMap<>(); - countMap.put(x, 1);
-
- List
res = new ArrayList<>(); - for (int i = N; i < s.length(); i++) {
- x = FF & ((x << 2) | map.get(s.charAt(i)));
- int count = countMap.getOrDefault(x, 0);
- count++;
- if (count == 2) {
- // 坑点
- res.add(s.substring(i - N + 1, i + 1));
- }
- countMap.put(x, count);
- }
-
- return res;
- }
-
- public static void main(String[] args) {
- Solution3 solution = new Solution3();
- System.out.println(solution.findRepeatedDnaSequences("AAAAAAAAAAAAA"));
- System.out.println(solution.findRepeatedDnaSequences("AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"));
- }
- }
这道题核心还是做优化,有点像孔乙己说茴香豆的茴有多少种写法;这里我提供了3种,如果有更高效、更简洁的代码欢迎回复。