LeetCode | 187. Repeated DNA Sequences

来源:互联网 发布:淘宝上怎么买到a货翡翠 编辑:程序博客网 时间:2024/05/29 02:54


题意:All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

所有DNA由四种核苷酸构成,分别是A, C, G, T,例如:"ACGAATTCCG"

先需要找到在输入序列中重复出现过的子串,子串长度限定为10。


例如:

Given s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT",Return:["AAAAACCCCC", "CCCCCAAAAA"].

值得注意的是输出要求去重,也就是说如果一个子串出现两次及以上,也只输出一次。


思路:

1. 暴力求解

    —— 直接将每个子串与后续进行比较,使用标记数组进行标注出现过的子串,如果是第一次重复出现则压入输出res向量。时间复杂度为O(n^2);这个解法经过部分优化还是超时。

2. Hashmap哈希标记

    —— 创建hash_map对应字符串和出现频率,<string, int>,对每个出现的子串查找是否存在,如果不存在则插入新的pair,记出现频次为1;如果子串存在哈希表中,判断出现频次是否为1,若为1,则说明本次重复出现是第一次,修改频次为2,并将当前子串压入输出向量。时间复杂度O(n),但是内存超了= =。

3. 压缩字符串+哈希表

    —— 注意输入字符串中只会出现四种字符,A, C, G, T,因而可以将它们分别对应为0,1,2,3,二进制分别对应为00,01,10,11,将10位的子串转换为二进制串,只需20位即可表示,使用int型作为哈希的索引,因而哈希表可改建为<int, int>。这里的思路参考了点击打开链接


C++代码如下:

vector<string> findRepeatedDnaSequences(string s) {        vector<string> res;        if(s.size() < 10)return res;unordered_map<int, int> DNA;unordered_map<char, int> types;types['A'] = 0; types['C'] = 1;types['G'] = 2; types['T'] = 3;int key = 0;for(int i = 0; i<s.size(); i++){key = ((key << 2) | types[s[i]]) & 0xfffff;if(i < 9)continue;if(DNA.find(key) == DNA.end())DNA[key] = 1;else if(DNA[key] == 1){DNA[key] = 2;res.push_back(s.substr(i-9, 10));}}return res;    }


运行结果:



注意:需要注意的问题是,Leetcode平台的C++编译环境下没有hash_map,将其替换为unordered_map即可。


欢迎大家一起讨论新思路!





0 0