# 字符串hash暴力串串题

#### Leetcode 28. 实现 strStr()

class Solution {
public:
typedef long long ll;
typedef unsigned long long ull;
const ull base = 233;
vector<ull>p, h;

void init(string s)
{
ll n = s.size();
p.resize(n+1, 1);
h.resize(n+1, 0);

for(int i=1;i<=n;i++)  h[i] = h[i-1]*base + (ull)s[i-1];
for(int i=1;i<=n;i++)  p[i] = p[i-1]*base;
}

inline ull gethash(int l,int r)  // 计算第l个 到第r的hash值
{
return h[r] - h[l-1]*p[r-l+1];
}

int strStr(string haystack, string needle) {
if(needle == "")  return 0;
ull target = 0;
for(char ch : needle) target = target*base + (ull)ch;

init(haystack);
int n = haystack.size(), m = needle.size();
int i = 1, j = m;
while(j <= n) {
// cout << gethash(i, i+m-1) << " " << target << endl;
if(gethash(i, j) == target)  return i-1;
i++;j++;
}
return -1;
}
};


#### Leetcode 49. 字母异位词分组

class Solution {
public:
int hash(string s)
{
unsigned int res = 0;
unsigned int base = 233;
sort(s.begin(), s.end());
for(char ch : s)
res = res*base + ch;  // 自然溢出
return (int)res;
}

vector<vector<string>> groupAnagrams(vector<string>& strs) {
unordered_map<int, vector<string>>mp;
for(string s : strs)
mp[hash(s)].push_back(s);
vector<vector<string>>ans;
for(auto it = mp.begin(); it != mp.end();it++)
ans.push_back(it->second);

return ans;
}
};


#### Leetcode 336.回文对

class Solution {
public:
typedef long long ll;
typedef unsigned long long ull;
const ull base = 233;

ull getHash(string& s, int n) {
ull hash = 0;
// int n = s.size();
for(int i = 0;i < n;i++)  hash = hash*base + s[i]-'a';
return hash;
}
ull getRHash(string& s, int n) {
ull hash = 0;
// int n = s.size();
for(int i = n-1;i >= 0;i--)  hash = hash*base + s[i]-'a';
return hash;
}

vector<vector<int>> palindromePairs(vector<string>& words) {
int n = words.size();
// hs.resize(n);
// rhs.resize(n);
// mul.resize(305);  // resize会超时
ull hs[n], rhs[n], len[n];
ull mul[305];
for(int i  = 0;i < n;i++) {
len[i] = words[i].size();   // 避免每次去求size，也是一个常数级优化 1036ms->568ms
hs[i] = getHash(words[i], len[i]);
rhs[i] = getRHash(words[i], len[i]);
}
for(int i = 0;i < 305;i++)  mul[i] = (i==0?1:mul[i-1]* base);

vector<vector<int>>ans;
for(int i = 0;i < n;i++) {
for(int j = 0;j < n;j++) {
if(i == j)  continue;
ull left = hs[i]*mul[len[j]] + hs[j];
ull right = rhs[i] + rhs[j]*mul[len[i]];
if(left == right)  ans.push_back({i,j});
}
}
return ans;
}
};


#### Leetcode 214. 最短回文串

class Solution {
public:
typedef unsigned long long ull;
ull base = 233;
string shortestPalindrome(string s) {
if(s=="") return "";
int n = s.size(), pos;
ull hs = 0, rhs = 0, mul = 1;
for(int i = 0;i < n;i++) {
hs = hs*base + s[i]-'a';
rhs = rhs + (s[i]-'a')*mul;
mul *= base;
if(hs == rhs)  pos = i;
}
string tmp = s.substr(pos+1);
reverse(tmp.begin(), tmp.end());
return tmp+s;
}
};

posted @ 2021-12-25 23:40  Rogn  阅读(22)  评论(0编辑  收藏  举报