LeetCode: 187.重复的DNA

56 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第16天,点击查看活动详情

187.重复的DNA

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re…

所有 DNA 都由一系列缩写为 'A','C','G' 和 'T' 的核苷酸组成,例如:"ACGAATTCCG"。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。

编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。

示例 1:

输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" 输出:["AAAAACCCCC","CCCCCAAAAA"]

示例 2:

输入:s = "AAAAAAAAAAAAA" 输出:["AAAAAAAAAA"]

提示:

  • 0<=s.length<=1050 <= s.length <= 10^5
  • s[i] 为 'A'、'C'、'G' 或 'T'

解法

  • 滑动窗+哈希表法: 给定固定长度,采用滑动窗口的方法去滑动窗口获得对应长度的字符串,使用哈希表存储字符串,将字符串作为key,出现次数作为value。如果value值大于等于2则表明这个字符串有重复。

  • python

class Solution:
    def findRepeatedDnaSequences(self, s: str) -> List[str]:
        if not s or len(s) < 10:
            return []
        n = len(s)
        res = {}
        ans = []
        for i in range(10, n+1):
            temp_str = s[i-10:i]
            if temp_str in res:
                res[temp_str] += 1
            else:
                res[temp_str] = 1
            if res[temp_str] >= 2 and temp_str not in ans:
                ans.append(temp_str)
        '''
        ans = []
        for k, v in res.items():
            if v > 1:
                ans.append(k)
        '''
        return ans
        
  • c++
class Solution {
    const int L = 10;
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        unordered_map<string, int> cnt;
        int n = s.length();
        for(int i=0; i <= n-L; i++)  // <=
        {
            string sub = s.substr(i, L);
            if(++cnt[sub] == 2)
            {
                ans.push_back(sub);
            }
        }
        return ans;
    }
};

复杂度分析

  • 时间复杂度:O(LN) 其中 N 是字符串s 的长度,L=10 即目标子串的长度

  • 空间复杂度:O(NL) 一个哈希表存储