重复的DNA序列
难度:
标签:
题目描述
DNA序列 由一系列核苷酸组成,缩写为 'A'
, 'C'
, 'G'
和 'T'
.。
- 例如,
"ACGAATTCCG"
是一个 DNA序列 。
在研究 DNA 时,识别 DNA 中的重复序列非常有用。
给定一个表示 DNA序列 的字符串 s
,返回所有在 DNA 分子中出现不止一次的 长度为 10
的序列(子字符串)。你可以按 任意顺序 返回答案。
示例 1:
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" 输出:["AAAAACCCCC","CCCCCAAAAA"]
示例 2:
输入:s = "AAAAAAAAAAAAA" 输出:["AAAAAAAAAA"]
提示:
0 <= s.length <= 105
s[i]
==
'A'
、'C'
、'G'
or'T'
代码结果
运行时间: 38 ms, 内存: 26.8 MB
/*
* 思路:
* 1. 使用Java Stream API遍历字符串s,获取所有长度为10的子字符串。
* 2. 使用Collectors.groupingBy计算每个子字符串的出现次数。
* 3. 过滤出出现次数大于1的子字符串并收集到结果列表中。
*/
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SolutionStream {
public List<String> findRepeatedDnaSequences(String s) {
if (s.length() < 10) return Collections.emptyList();
return IntStream.rangeClosed(0, s.length() - 10)
.mapToObj(i -> s.substring(i, i + 10))
.collect(Collectors.groupingBy(str -> str, Collectors.counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() > 1)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
解释
方法:
该题解采用滑动窗口和位操作的方法来寻找重复的DNA序列。首先,将四个可能的字符('A', 'C', 'G', 'T')映射到2位的整数(分别是0, 1, 2, 3),以便使用位操作来更新当前窗口的哈希值。使用一个长度为10的滑动窗口,遍历字符串,每向右移动窗口一位,就更新当前窗口表示的数字(通过左移两位并添加新字符的映射值,同时确保数字长度不超过20位,即10个字符的长度)。每个窗口的数字作为哈希表的键,记录每个序列出现的次数。当某个序列第二次出现时,将其添加到结果列表中。这种方法避免了直接使用字符串子串比较,而是通过计算较小的整数值来优化比较过程。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么选择长度为10的窗口来寻找重复的DNA序列?是否有特定的生物学或算法上的原因?
▷🦆
在位操作中,你如何确保通过左移和添加新字符的值时,数字长度不会超过20位?详细解释使用的位操作和掩码。
▷🦆
为什么在DNA序列映射时选择将'A', 'C', 'G', 'T'映射到2位的整数,而不是其他位数?
▷