【LeetCode】5994. 查找给定哈希值的子串
1 class Solution { 2 public: 3 string subStrHash(string s, int p, int m, int k, int hash) { 4 int n = s.size(); 5 unsigned long long pow[20010]; //long long防止溢出 6 pow[0] = 1; 7 for (int i = 1; i <= k; ++i) { 8 pow[i] = (pow[i - 1] * p) % m; //提前计算power的k次幂 9 } 10 11 for(int i=0;i<n;++i) //初始化字母代表的数值,方便代码书写 12 { 13 s[i]-='a'-1; 14 } 15 16 int ans; 17 unsigned long long sum=0; 18 19 for(int j=0; j<k ; ++j) //对第一个窗口n-k~n-1进行特殊判断 20 { 21 sum=(sum+(s[n-k+j])*pow[j]) % m; 22 } 23 if(sum==hash) 24 { 25 ans=n-k; 26 } 27 28 for (int i = n-k-1 ; i >=0 ; i--) //滑动窗口 29 { 30 sum=(sum*p-((s[i+k])*pow[k])%m+s[i]+m)%m; //加m以防止变为负数 31 if(sum==hash) 32 { 33 ans=i; 34 } 35 } 36 37 string b; 38 for(int j=0;j<k;++j) 39 { 40 b+=(s[ans+j]+('a'-1)); //还原结果,加上'a'-1 41 } 42 43 return b; 44 } 45 };
思路基本写在注释里了。
观察题意,因为解的结构的相似性,所以很容易联想到滑动窗口算法;但是由于除法不满足取模公式,所以这个滑动窗口需要倒着滑。
首先构造初始窗口,再用循环依次滑到最开始,因为要求最先出现的子串,所以得遍历一遍字符串。
代码中做了存储幂结果的优化,以及使用long long防止溢出。

浙公网安备 33010602011771号