LeetCode | 187. Repeated DNA Sequences

本文介绍了一种高效的方法来寻找DNA序列中重复出现的长度为10的子串,通过使用哈希表和二进制压缩技术,实现了时间和空间效率的双重优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题意: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即可。


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





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值