哈尔滨网站建设公司网站如何发布
哈希表
直观思考,由于限定了答案长度 101010 ,只需要一次遍历字符串,统计所有长度为 101010 的子串的出现次数(哈希表) ,最后遍历哈希表,维护答案,记录出现 222 次(及以上)的字符串 。
class Solution {
public:vector<string> findRepeatedDnaSequences(string s) {unordered_map<string,int> mp;for(int i = 0;i+10<=s.size();i++)mp[s.substr(i,10)]++;vector<string> ans;for(auto &[S,V]:mp)if(V>=2) ans.push_back(S);return ans;}
};
时间复杂度 : O(n×∣C∣)O(n\times |C|)O(n×∣C∣) , 字符串长度 nnn , 核苷酸长度 ∣C∣=10|C|=10∣C∣=10 ,一边遍历字符串,统计每个长度为 101010 的子串,时间复杂度 O(n×∣C∣)O(n\times |C|)O(n×∣C∣) 。
空间复杂度 : O(n×∣C∣)O(n\times |C|)O(n×∣C∣) , 哈希表的最坏空间复杂度 O(n×∣C∣)O(n\times |C|)O(n×∣C∣) 。
字符串哈希
给定一个字符串,判断两个子串是否相同的问题 ,更为高效的做法是字符串哈希 : 将字符串的每一位看做 PPP 进制数,整个字符串就是个很大的 PPP 进制数 。判断某两个子串是否相同,转化为判断整个子串对应的数字是否相同。类比十进制考虑。
class Solution {
public:// ULL get(int l,int r){// return h[r] - h[l]*p[r-l+1];// }vector<string> findRepeatedDnaSequences(string s) {const int P = 13331;const int N = s.size() + 1;typedef unsigned long long ULL;unordered_map<ULL,int> mp;vector<string> ans;ULL h[N], p[N];h[0] = 0,p[0] = 1;for(int i = 1;i<N;i++){h[i] = h[i-1]*P + s[i-1];p[i] = p[i-1]*P;}for(int i = 10;i<N;i++){ULL hash_val = h[i] - h[i-10]*p[10];mp[hash_val]++;if(mp[hash_val]==2) ans.push_back(s.substr(i-10,10));}return ans;}
};
时间复杂度 : O(n)O(n)O(n) , 字符串长度 nnn , 只进行常数次遍历,时间复杂度 O(n)O(n)O(n) 。
空间复杂度 : O(n)O(n)O(n) , 哈希表的空间复杂度 O(n)O(n)O(n) 。
AC
致语
- 理解思路很重要!
- 欢迎读者在评论区留言,墨染看到就会回复的。