Leetcode:Repeated DNA Sequences

Kotlin+Spring Boot开发REST API实战 Kotlin与JAVA对比简洁之处、不同之处;从基础配置、Entity、Repository、REST Controller,到异常处理、Security、测试、集成Swagger,一步步学习Kotlin+Spring Boot开发。 阅读详情

转自:http://www.tuicool.com/articles/AnuQJjA 

hash table plus bit manipulation method

(view the Show Tags and Runtime 10ms !)

算法分析

首先考虑将ACGT进行二进制编码

A -> 00

C -> 01

G -> 10

T -> 11

在编码的情况下,每10位字符串的组合即为一个数字,且10位的字符串有20位;一般来说int有4个字节,32位,即可以用于对应一个10位的字符串。例如

ACGTACGTAC -> 00011011000110110001

AAAAAAAAAA -> 00000000000000000000

20位的二进制数,至多有2^20种组合,因此hash table的大小为2^20,即1024 * 1024,将hash table设计为bool hashTable[1024 * 1024];(注意:若此时出现堆栈溢出,可申请动态内存,但一定要记得在最后释放,否则会MLE)

遍历字符串的设计

每次向右移动1位字符,相当于字符串对应的int值左移2位,再将其最低2位置为新的字符的编码值,最后将高2位置0。

时间复杂度

字符串遍历O(n),hash tableO(1);总时间复杂度O(n)

代码实现

 1 #include <string>
 2 #include <vector>
 3 #include <unordered_set>
 4 #include <cstring>
 5 
 6 bool hashMap[1024*1024];
 7 
 8 class Solution {
 9 public:
10     std::vector<std::string> findRepeatedDnaSequences(std::string s);
11 };
12 
13 std::vector<std::string> Solution::findRepeatedDnaSequences(std::string s) {
14     std::vector<std::string> rel;
15     if (s.length() <= 10) {
16         return rel;
17     }
18 
19     // map char to code
20     unsigned char convert[26];
21     convert[0] = 0; // 'A' - 'A'  00
22     convert[2] = 1; // 'C' - 'A'  01
23     convert[6] = 2; // 'G' - 'A'  10
24     convert[19] = 3; // 'T' - 'A' 11
25 
26     // initial process
27     // as ten length string
28     memset(hashMap, false, sizeof(hashMap));
29 
30     int hashValue = 0;
31 
32     for (int pos = 0; pos < 10; ++pos) {
33         hashValue <<= 2;
34         hashValue |= convert[s[pos] - 'A'];
35     }
36 
37     hashMap[hashValue] = true;
38 
39     std::unordered_set<int> strHashValue;
40 
41     // 
42     for (int pos = 10; pos < s.length(); ++pos) {
43         hashValue <<= 2;
44         hashValue |= convert[s[pos] - 'A'];
45         hashValue &= ~(0x300000);
46         
47         if (hashMap[hashValue]) {
48             if (strHashValue.find(hashValue) == strHashValue.end()) {
49                 rel.push_back(s.substr(pos - 9, 10));
50                 strHashValue.insert(hashValue);
51             }
52         } else {
53             hashMap[hashValue] = true;
54         }
55     }
56 
57     return rel; 
58 }

另外一个解释:http://blog.youkuaiyun.com/coderhuhy/article/details/43647731

思路历程:

-- 这是一个子串对自身匹配的问题;

-- 第一反应有3种方法: 其一, 使用hash(c++11的unordered_set)来存储所有长度为10的子串; 具体步骤是构造unordered_set<string> repeated, 遍历输入的原串, 对s[i]到s[i+9]的序列构成的子串, 如未出现在repeated中, 则存入repeated; 如出现在repeated中, 则说明该子串曾出现过, 符合题意要求, 将其存入答案vector<string> answer;

当然, 这个代码最后是memory limit exceeded; 先看代码, 后面分析;


[cpp]  view plain copy
  1. class Solution {  
  2. public:  
  3.     vector<string> findRepeatedDnaSequences(string s) {  
  4.         vector<string> answer;  
  5.         unordered_set<string> repeated;  
  6.         for (int i = 0; i + 9 < s.size(); ++i) {  
  7.             string t(s, i, 10);  
  8.             unordered_set<string>::iterator it = repeated.find(t);  
  9.             if (it != repeated.end())  
  10.                 answer.push_back(t);//在repeated中查找成功, 说明曾出现过该子串, 则存入answer  
  11.             else  
  12.                 repeated.insert(t);//repeated中查找失败, 说明未曾出现过, 则存入repeated  
  13.         }  
  14.         return answer;  
  15.     }  
  16. };//memory limit exceeded  

分析:

时间复杂度是O(n), 其中n为原串长度;

MLE的可能原因: unordered_set<string>对于超长的输入串, 会消耗大量的存储空间; 另外, 上面代码并未考虑answer中的重复答案, 因为每次只要出现在repeated中就放入answer, 这显然有问题;


改进方法:

-- 由于碱基无非ACGT四种类型, 可以使用00 01 10 11四个状态代替ACGT四种碱基, 比如AAGCT就是00 00 10 01 11, 对任意一个长度为10的子串都可以转化使用20个位的int值hint; 这样就可将unordered_set<string> repeated转变为unordered_set<int> repeated, 一定程度上减少了所需的存储空间;

-- 对于如何去重, 其一可以先收集所有答案, 再sort, unique去重, 当然这样很慢也很麻烦; 其二, 可以再构造一个unordered_set<int> check, 用于存储已经存入answer中的重复子串对应的hint值;

-- 值得一提的是, 每次从s[i]->s[i+9]变为s[i+1]->s[i+10], 使用了这样一个方法:

[cpp]  view plain copy
  1. hint = ((hint & eraser) << 2) + ati[s[i]];  
其中eraser是一个宏定义, 值为0x3ffff, 二进制是00111111111111111111, 用于擦除hint中的最高2位s[i]碱基对应的值, 再左移2, 最后加上s[i+10]的碱基对应的值;

代码如下:

[cpp]  view plain copy
  1. class Solution {  
  2. public:  
  3.     #define eraser 0x3ffff  
  4.     vector<string> findRepeatedDnaSequences(string s) {  
  5.         vector<string> answer;  
  6.         int hint = 0;//存储长度为10的子串翻译后的int值  
  7.         if (s.size() < 10)  
  8.             return answer;  
  9.         unordered_set<unsigned int> repeated, check;//repeated存储已出现的子串, check用于防止重复答案  
  10.         unordered_map<char, unsigned int> ati{{'A', 0}, {'C', 1}, {'G', 2}, {'T', 3}};//此处ati是存储各碱基对应的值00 01 10 11(c++11新语法)  
  11.         for (int i = 0; i != 10; ++i) {  
  12.             hint = (hint << 2) + ati[s[i]];//用s的前10个碱基构造初始hint值  
  13.         }  
  14.         repeated.insert(hint);  
  15.         for (int i = 10; i != s.size(); ++i) {  
  16.             hint = ((hint & eraser) << 2) + ati[s[i]]; //子串变化对应hint值变化  
  17.             unordered_set<unsigned int>::iterator it = repeated.find(hint);  
  18.             if (it != repeated.end()) {  
  19.                 it = check.find(hint);  
  20.                 if (it == check.end()) {  
  21.                     answer.push_back(string(s, i - 9, 10));  
  22.                     check.insert(hint);  
  23.                 }  
  24.             }  
  25.             else  
  26.                 repeated.insert(hint);  
  27.         }  
  28.         return answer;  
  29.     }  
  30. };  
分析:

一开始由于忽略了移位与其他运算符的优先级关系, 一直出问题, 后来才发现

[cpp]  view plain copy
  1. hint = ((hint & eraser) << 2) + ati[s[i]];  
里面的外面那层括号没加上, 浪费了不少时间, 确实不应该
保姆级教程:在RV1126开发板上跑通YOLOv5口罩检测(从数据集到摄像头实时识别) 本文提供了一份详细的RV1126开发板部署YOLOv5口罩检测系统的全流程指南,涵盖数据集准备、模型训练优化、边缘部署及实时摄像头识别等关键步骤。重点解析了RV1126开发板的性能特征、YOLOv5模型训练调优技巧、RKNN模型转换量化策略,以及部署过程中的性能优化方案,帮助开发者高效实现边缘端目标检测应用。 阅读详情

相关推荐

微信小程序 实现拼图功能

微信小程序 实现碎片拼图

weixin_45689786的博客 2250

Leetcode 187、重复的DNA序列

Problem Source : https://leetcode-cn.com/problems/repeated-dna-sequences/ Solution Source : https://github.com/hujingbo98/algorithm/blob/master/source/leetcode/0187_RepeatedDNASequences.cpp 187、重复的DNA序列 所有 DNA 都由一系列缩写为 ‘A’,‘C’,‘G’ 和 ‘T’ 的核苷酸组成,例如:“ACGAATT.

博弈的博客 395

如何实现Docker镜像导入导出 ?

摘要: Docker镜像迁移与备份可通过两种方式实现:1)镜像操作(save/load)完整保存分层结构和元数据,适用于完整备份;2)容器操作(export/import)仅保存文件系统快照,适合创建轻量模板。关键区别在于前者保留历史记录和分层,后者生成单层镜像。save/load命令示例:docker save -o nginx.tar nginx:latest,export/import示例:docker export -o container.tar abc123 && docker

weixin_39291964的博客 875

雪花算法揭秘时刻

ID的生成有很多的方式,使用雪花算法带来的好处:毫秒数在高位,自增序列在低位,整个ID都是趋势递增的; 不依赖数据库等第三方系统,以服务的方式部署,稳定性能高,生成ID的性能也是非常高的;可以分局自身业务特性分配bit位,非常灵活

刘亚男 690

“华为杯”研究生数学建模竞赛2020年-【华为杯】E题:能见度估计与预测(附获奖论文及python代码实现)

因此,题目要求借助机场的 AMOS 观测数据中的气压、温度、湿度、风速等气象因子,达到 100% 时,空气中的水汽便会凝结成细微的水滴悬浮于空中,使地面水平的能见度下。传统的仪器探测法成本高,覆盖范围小,而基于视频的能见度检测能弥补仪器测量的不足之处,但是预测精度不高,需要进一步改。象条件,空气质量的影响,其中较为关键的影响因子是雾和霾。性过强,激光能见度仪的检测方法更为可信,但是激光能见度仪覆盖的检测范围小,安装。覆盖的交通视频路况数据间接计算得到能见度数值的方法,此方法成本较低,覆盖范围广。

getusushu的博客 2280

锐明技术Crocus系统 DeviceState.do SQL注入漏洞复现

锐明技术Crocus系统 DeviceState.do 接口存在SQL注入漏洞,经过身份验证的远程攻击者除了可以利用SQL注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

0xSec 452

aardio - 利用customPlus库+plus构造一个多按钮组件

利用customPlus库+plus组件,轻松构造一个多按钮组件,实现鼠标悬停效果,实现响应点击功能。

光庆的学习笔记 2228

[Dify]-进阶5- 使用 Dify 构建多轮对话的客服机器人

本文介绍了如何利用Dify平台构建智能客服系统,重点阐述了ChatFlow框架的应用。系统支持多轮对话、业务接口集成和话术策略管理,具备订单查询、退货申请等核心功能。通过Classifier节点实现意图识别,借助Router节点分流处理流程,并结合API插件实现业务数据对接。文章还提供了部署调试、会话优化和监控分析的具体方法,强调模块化设计和插件化集成的重要性,为构建功能完善的智能客服系统提供了完整解决方案。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1659

Java堆内存溢出造成OS卡顿/服务中断的一种情况

前提 top看内存情况 目标 测试内存临界情况下,内存溢出对已运行Java服务的影响 过程 1、制造麻烦 public static void main(String[] argv) { Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread

积累与备忘 6859

Modelsim:LPDDR5仿真(含美光仿真模型官方sv&vcs代码)

虽然,三星在设计跟量产上,早于其他家存储产商,但是镁光后来居上了,是业界首家支持全速 LPDDR5 的供应商,并且开发者在做开发的时候,也是用美光颗粒比较多,所以这里就先以美光的仿真模型为主进行仿真。 本工程为美光官方工程,支持Modelsim、VCS、ncverilog三种仿真器仿真。模型破解过,为完整system-verilog代码。

千歌叹尽执夏的博客 1281

华为OD机试真题2025双机位B卷 Python&JS 实现【朋友圈个数】

给定一组朋友关系,统计一下该朋友关系网中的朋友圈个数。 朋友圈的定义:一个朋友圈至少由3个朋友组成,且要求同一个朋友圈中的任意两个人都具有直接的朋友关系。 输入描述 输入一个朋友关系列表,如 Fiends =A.B],[A.C],IB,DI,其中的每一个元素 Friendsi表示 Friends[i][0)和 Friends [i][1] 是朋友关系 先输入一个数字 N 代表关系的总数,后面每条关系一行,两个成员以逗号分隔

MISAYAONE的博客 562

Leetcode161: Repeated DNA Sequences

原文地址 : https://so.youkuaiyun.com/so/search/s.do?q=leetcode161&t=%20&u= All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it...

Umbrella Corporation 9627

TBOX电源方案的详细讲解与分析

输入保护电路是确保车载电子系统稳定性的关键。通过合理选择TVS二极管、保险丝和浪涌抑制器等元器件,能够有效防止来自电源系统的瞬态过电压、浪涌和过流问题,保护后续电路免受损害。针对不同的电源环境和应用场景,可以通过提升功率、优化热管理以及选择高效元器件来进一步提高系统的保护能力和可靠性。

weixin_43199439的博客 1074

leetcode 187: Repeated DNA Sequences

Total Accepted: 1161 Total Submissions: 6887 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 usef

西施豆腐渣 6033

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Leetcode:Repeated DNA Sequences

开始看到题目,觉得就是直接从第一个子字符串开始遍历,并存储在List中,如果某个子字符串出现两次,就将其添加到结果列表中。结果TLE(Time Limited Exceeded)了。代码如下: public class Solution { public List findRepeatedDnaSequences(String s) { List res

redstraw的专栏 2577

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Leetcode: Repeated DNA Sequences

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. Write

YMHH的专栏 430

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

LeetCode:Repeated DNA Sequences

问题: 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.

cy736732813的专栏 365

LeetCode: Repeated DNA Sequences

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. Wri

557

leetcode:Repeated DNA Sequences

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. Wri

愤怒的菜鸟专栏 254

《leetCode》:Repeated DNA Sequences

题目:Repeated DNA SequencesAll 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 sequen

wojiushimogui的博客 574

Leetcode187: Repeated DNA Sequences

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. Wri

~\(≧▽≦)/~ 274

leetcode:Repeated DNA Sequences

class Solution { public: char hash[1024*1024]; vector findRepeatedDnaSequences(string s) { vector res; if(s.size()<10) return res; char convertor[26];

没有趟不过的河 488

LeetCode: 187. Repeated DNA Sequences

LeetCode: 187. Repeated DNA Sequences 解题思路 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 ide...

杨领well的专栏 192
上一篇: 字符串移位包含的问题
下一篇: 计算字符串的相似度
SHForWork
博客等级 码龄12年 11粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值