玩命加载中 . . .

187-重复的DNA序列


LeetCode 187. 重复的DNA序列

DNA 序列由一系列核苷酸组成,缩写为 'A', 'C', 'G''T'.。

例如,"ACGAATTCCG" 是一个DNA序列 。
在研究 DNA 时,识别 DNA 中的重复序列非常有用。

给定一个表示 DNA 序列 的字符串 s ,返回所有在 DNA 分子中出现不止一次的 长度为 10 的序列(子字符串)。你可以按 任意顺序 返回答案。

示例 1:

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

method

维护一个长度为10的滑动窗口,如果窗口内的子串已经出现一次,就把该子串加入到结果中

vector<string> findRepeatedDnaSequences(string s) {
    int n = s.size();
    vector<string> res;
    unordered_map<string, int> hash;
    for (int i = 0; i + 10 <= n; i++) {
        string str = s.substr(i, 10);
        if (++hash[str] == 2) {     // 防止重复添加
            res.push_back(str);
        }
    }
    return res;
}

也可以用字符串哈希

子串s[i:j]的哈希值可以通过h[j]-h[i-1]*p[j-i+1]求得,运用了前缀和的思想

因为这里子串长度是固定的,所以$power=prime^{10}$固定了,就不用hash数组和power数组了

const int prime = 31;
vector<string> findRepeatedDnaSequences(string s) {
    unsigned long long hash = 0;
    unsigned long long power = 1;
    
    for (int i = 0; i < 10; i++) {
        hash = hash * prime + (s[i] - 'a');
        power *= prime;
    }
    vector<string> res;
    unordered_map<unsigned long long, int> exits;
    exits[hash] = 1;
    for (int i = 10; i < s.size(); i++) {
        hash = hash * prime - power * (s[i - 10] - 'a') + (s[i] - 'a');
        if (++exits[hash] == 2) res.push_back(s.substr(i - 10 + 1, 10)); 
    }
    return res;
}

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录