重复的DNA序列(repeated-dna-sequences)

重复的DNA序列(repeated-dna-sequences)

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

编写一个函数来查找 DNA 分子中所有出现超过一次的 10 个字母长的序列(子串)。

示例:

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

思路与代码

解法一(暴力,双层循环,java)

public List<String> findRepeatedDnaSequences(String s) {
    int len = s.length();
    Set<String> res = new HashSet<String>();
    for (int i = 0; i <= len - 10; i++) {
        for (int j = i + 1; j <= len - 10; j++) {
            if (s.substring(i, i + 10).equals(s.substring(j, j + 10))) {
                res.add(s.substring(i, i + 10));
                break;
            }
        }
    }
    return new ArrayList<>(res);
}

解法二(滑动窗口,java)

class Solution {
    public List<String> findRepeatedDnaSequences(String s) {
        List<String> res=new ArrayList<>();
        //s长度小于等于10当然不会有重复子串
        if(s.length()<=10)
            return res;
        //窗口大小
        int window=10;
        int start=0;
        //记录出现过的子串
        Map<String,Integer> sMap=new HashMap<>();
            //左为0,右为窗口大小,开始滑动每轮while循环lr自增1
            int l=0;
            int r=window;
            while(r<=s.length()){
                //获取当前子串
                String temp=s.substring(l,r);
                //如果已经记录存在,返回对应value值,否则返回1
                int count=sMap.getOrDefault(temp,0);
                //value值加1,存入map
                sMap.put(temp,count+1);
                //第一次重复出现的时候加入list,之后再出现此单词不用加入list了,等于去重
                if(count==1){
                    res.add(temp);
                }
                l++;
                r++;
            }
        return res;
    }
}

解法三(哈希,java)

public List<String> findRepeatedDnaSequences(String s) {
    int len = s.length();
    Set<String> res = new HashSet<>();
    Set<String> set = new HashSet<>();
    for (int i = 0; i <= len - 10; i++) {
        String key = s.substring(i, i + 10);
         //之前是否存在
        if (set.contains(key)) {
            res.add(key);
        } else {
            set.add(key);
        }

    }
    return new ArrayList<>(res);
}

解法四(哈希,java,解法二的优化版)

目前还看不懂,有空再回来看看。参考资料

public List<String> findRepeatedDnaSequences(String s) {
    int len = s.length();
    if (len == 0 || len < 10) {
        return new ArrayList<>();
    }
    Set<String> res = new HashSet<>();
    Set<Integer> set = new HashSet<>();
    int key = 0;
    char[] array = s.toCharArray();
    for (int i = 0; i < 10; i++) {
        key <<= 3;
        key |= (array[i] & 7);
    }
    set.add(key);
    for (int i = 10; i < len; i++) {
        key <<= 3;
        key |= (array[i] & 7);
        key &= 0x3fffffff;
        if (set.contains(key)) {
            res.add(s.substring(i - 9, i + 1));
        } else {
            set.add(key);
        }

    }
    return new ArrayList<>(res);
}

解法五(哈希,cpp,跟解法三一样的)

class Solution {
public:
    vector<string> findRepeatedDnaSequences(string s) {
    	std::map<std::string, int> word_map;//单词,单词数量的映射
    	std::vector<std::string> result;
    	for (int i = 0; i < s.length(); i++){
    		std::string word = s.substr(i, 10);
	    	if (word_map.find(word) != word_map.end()){
	    		word_map[word] += 1;
	    	}
	    	else{
	    		word_map[word] = 1;
	    	}
	    }
	    std::map<std::string, int> ::iterator it;
	    for (it = word_map.begin(); it != word_map.end(); it++){
    		if (it->second > 1){
		    	result.push_back(it->first);
		    }
    	}
    	return result;        
    }
};

执行用时 :184 ms, 在所有 C++ 提交中击败了26.57%的用户
内存消耗 :24.1 MB, 在所有 C++ 提交中击败了51.88%的用户

发布了151 篇原创文章 · 获赞 47 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/e891377/article/details/103866781