Skip to main content

187.重复的DNA序列

标签: hash-table, string, bit-manipulation

难度: Medium

通过率: 50.22%

原题链接: https://leetcode.com/problems/repeated-dna-sequences/description/

题目描述

DNA序列由以 'A'、'C'、'G' 和 'T' 表示的核苷酸组成。对于一个给定的字符串 ss,表示DNA序列,请输出在DNA分子中出现超过一次的所有长度为10的序列(子字符串)。可以以任意顺序返回答案。

解题思路

要解决这个问题,我们可以使用滑动窗口的技术来遍历字符串,同时利用哈希表来记录出现过的序列,寻找重复的序列。具体步骤如下:

  1. 使用哈希集合 seen 来记录我们已经遇到的序列。
  2. 使用另一个哈希集合 repeated 来记录出现过多次的序列。
  3. 遍历字符串 s,从开头到倒数第10个字符,取出每个长度为10的子字符串。
  4. 对于每个子字符串:
    • 如果子字符串已经在 seen 中出现过,且不在 repeated 中,将其加入 repeated,表示重复出现。
    • 否则,将其加入 seen
  5. 最终返回 repeated 中的所有序列作为结果。

这种方法的优点在于,我们不需要对10个字符的子串进行大量比较(直接比较字符串即可),利用哈希集合有效地记录和查找出现的序列。

代码实现

def findRepeatedDnaSequences(s: str) -> list:
# 定义两个集合来保存过程中的数据
seen = set()
repeated = set()

# 遍历字符串,取出每一个连续的10个字符的子字符串
for i in range(len(s) - 9):
current_substr = s[i:i+10]
# 检查当前子串是否已经出现过
if current_substr in seen:
repeated.add(current_substr)
else:
seen.add(current_substr)

# 返回所有重复的DNA序列
return list(repeated)

复杂度分析

时间复杂度:由于我们需要遍历字符串,每次检查长度为10的子串,所以时间复杂度为 O(n)O(n),其中 nn 是字符串的长度。

空间复杂度:使用了两个集合来记录至少出现两次的子串和所有出现过的子串,因此空间复杂度为 O(n)O(n)