1. 程式人生 > >【LeetCode】187. 重複的DNA序列 結題報告 (C++)

【LeetCode】187. 重複的DNA序列 結題報告 (C++)

題目描述:

所有 DNA 由一系列縮寫為 A,C,G 和 T 的核苷酸組成,例如:“ACGAATTCCG”。在研究 DNA 時,識別 DNA 中的重複序列有時會對研究非常有幫助。

編寫一個函式來查詢 DNA 分子中所有出現超多一次的10個字母長的序列(子串)。

示例:

輸入: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

輸出: ["AAAAACCCCC", "CCCCCAAAAA"]

解題方案:

使用雜湊表進行儲存就好了,但是沒有用到位運算。。。

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
        map<string,int> mp;
        vector<string> ans;
        if(s.length()<10)
            return ans;
        for(int i=0;i<=s.length()-10;i++){
            string temp = s.substr(i,10);
            if(mp.find(temp)!=mp.end())
                mp[temp] = mp[temp] + 1;
            else
                mp[temp] = 1;
        }
        for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++){
            if(it->second>1)
                ans.push_back(it->first);
        }
        return ans;
    }
};

給出最短時間的答案:

class Solution {
public:
	vector<string> findRepeatedDnaSequences(string s) {
	if (s.size() <= 10)
		return vector<string>();

	vector<string> R;
	bitset<1 << 20> S1;
	bitset<1 << 20> S2;

	int val = 0;
	for (int i = 0; i < 10; i++)   // Calc. the has value for the first string.
		val = (val << 2) | char2val(s[i]);
	S1.set(val);

	int mask = (1 << 20) - 1;
	for (int i = 10; i < s.size(); i++) {
		// Calc the hash value for the string ending at position i.
		val = ((val << 2) & mask) | char2val(s[i]);
		if (S2[val])
			continue;
		if (S1[val]) {
			R.push_back(s.substr(i - 10 + 1, 10));
			S2.set(val);
		}
		else
			S1.set(val);
	}
	return R;
}

int char2val(char c) {
	switch (c) {
	case 'A': return 0;
	case 'C': return 1;
	case 'G': return 2;
	case 'T': return 3;
	}
}
};