每天一道LeetCode-----寻找给定字符串中重复出现的子串
2018-02-26 20:54
489 查看
Repeated DNA Sequences
原题链接Repeated DNA Sequences在给定字符串中寻找重复出现的序列,每个序列长度为10
可以采用unordered_map记录每个序列出现的个数,将出现超过一次的添加到结果集中
代码如下
class Solution { public: vector<string> findRepeatedDnaSequences(string s) { if(s.size() < 10) return {}; vector<string> res; unordered_map<string, int> hash; size_t first = 0; size_t last = 10; while(last <= s.size()) { auto str = s.substr(first, last - first); if(hash[str] == 1) res.emplace_back(str); ++hash[str]; ++first; ++last; } return res; } };
但是这种方法每次都需要调用substr获取子串,容易造成性能瓶颈,有什么方法不用调用substr也能判断当前的这个子串出现过呢
由于规定了子串长度为10,而且子串中只能出现”AGCT“四个字符中的一个,那么可以考虑用20个bit来表示长度为10的子串,其中每个字符占两bit。随后采用滑动窗口的思想,新到的字符添加到20bit的低位,溢出的字符丢掉
代码如下
class Solution { public: vector<string> findRepeatedDnaSequences(string s) { if(s.size() < 10) return {}; vector<string> res; unordered_map<int, int> hash; int val = 0; /* 掩码,用于将左溢出的两位清零 */ int mask = (1 << 20) - 1; /* 每个字符占两位,toBit要保证能区分开四个字符 */ for(int i = 0; i < 10; ++i) val = (val << 2) | toBit(s[i]); hash[val] = 1; for(int i = 10; i < s.size(); ++i) { val = ((val << 2) | toBit(s[i])) & mask; if(hash[val] == 1) res.emplace_back(s.substr(i - 10 + 1, 10)); ++hash[val]; } return res; } private: int toBit(char ch) { switch(ch) { case 'A': return 0; case 'G': return 1; case 'C': return 2; case 'T': return 3; } } };
相关文章推荐
- 每天一道LeetCode-----摩尔投票法寻找给定数组中出现个数大于n/2或n/3的元素
- 每天一道LeetCode-----给定大小为n+1的数组,元素大小在[1 : n]之间,只有一个元素会重复出现多次,找到重复的那个
- 每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求
- leetcode第三题:求给定字符串中最长无重复子串的长度
- 每天一道LeetCode-----找到一个字符串在另一个字符串出现的位置,字符串内部顺序无要求
- 每天一道LeetCode-----在字符串s中找到最短的包含字符串t中所有字符的子串,子串中字符顺序无要求且可以有其他字符
- 每天一道算法题(25)——字符串中连续出现次数最多的子串
- 【每天学点算法题10.17】寻找一个字符串中的最长重复子串
- 每天一道算法题(25)——字符串中连续出现次数最多的子串
- Python实现针对给定字符串寻找最长非重复子串的方法
- 每天一道LeetCode-----判断给定字符串是否符合某个模式
- leetcode-java.T003_LongestSubstringWithoutRepeatingCharacters 给定一个字符串,找字符中的最大非重复子串
- 每天一道LeetCode-----将字符串切分成若干单词,使得每个单词都在给定的字典中,求出所有的切分结果
- 每天一道LeetCode-----最长无重复子串
- 每天一道LeetCode-----将字符串切分,使每个子串都是回文串,计算所有可能结果和最小切分次数
- 算法题目二:寻找最长重复子序列(4) 求给定字符串重复最长的子串
- leetcode 459. Repeated Substring Pattern 重复子串的确定 + 不需要寻找重复出现的子串 + 暴力拼接即可
- 每天一道LeetCode-----有序数组循环右移n位后,寻找最小值,数组中可能包含重复元素
- 【寻找一个字符串中最长的重复子串】
- 对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符。 给定一个字符串(不一定全为字母)A及它的长度n。请返回第一个重复出现的字符。保证字符串中有重复字符,字符串的长度小于等于500。