《LeetCode之每日一题》:172.重复的DNA序列

重复的DNA序列

  • 有关题目
    • 题解

题目链接: 重复的DNA序列

有关题目

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

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

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

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

0 <= s.length <= 10^5
s[i]'A''C''G''T'

题解

法一:哈希表

class Solution {
	//const int L = 10;方便结构化管理
public:
    vector<string> findRepeatedDnaSequences(string s) {
    	vector<string> ans;
        int n = s.size();
        if (n <= 10)
        	return ans;
        
        unordered_map<string, int> mp;
        for (int i = 0; i <= n - 10; ++i)
        {
            string str = s.substr(i, 10);
            if (++mp[str] == 2)
                ans.push_back(str);
        }
        return ans;
    }
};

《LeetCode之每日一题》:172.重复的DNA序列_第1张图片
法二:位运算 + 哈希表 + 滑动窗口
参考官方题解
Tips

s.size()的返回值是无符号整数,计算的为s的长度,不是大小。
s.size() -  10,计算完结果则会变为无符号的整数,有符号整数中的负数转化为无符号整数可能会很大。
class Solution {
    const int L = 10;
    unordered_map<char, int> bin = {{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};
public:
    vector<string> findRepeatedDnaSequences(string s) {
        vector<string> ans;
        int n = s.size();
        if (n <= L)
            return ans;
        
        int x = 0;
        for (int i = 0; i < L - 1; ++i)
        {
            x = (x << 2) | bin[s[i]];
        }

        unordered_map<int, int> cnt;
        for (int i = 0; i <= n - L; ++i)
        {
            x = ((x << 2) | bin[s[i + L - 1]]) & ((1 << L * 2) - 1);
            if (++cnt[x] == 2)//防止了多次添加重复的元素
                ans.push_back(s.substr(i, L));
        }
        
        return ans;
    }
};

《LeetCode之每日一题》:172.重复的DNA序列_第2张图片

你可能感兴趣的:(LeetCode,leetcode,算法,哈希表,滚动数组,位运算)