力扣第373场周赛
循环移位后的矩阵相似检查
模拟,(j+k)%m计算右移,(j-k+m)%m计算左移
class Solution {
public:
bool areSimilar(vector<vector<int>>& mat, int k) {
int n = mat.size() , m = mat[0].size();
k %= m;
int ans[n][m];
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < m ; j ++){
if(i & 1)ans[i][(j+k)%m] = mat[i][j];
else ans[i][(j-k+m)%m]=mat[i][j];
}
}
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < m ; j ++){
if(ans[i][j] != mat[i][j])return false;
}
}
return true;
}
};
统计美丽子字符串 I
前缀和暴力
class Solution {
public:
int beautifulSubstrings(string s, int k) {
int n = s.size();
int v[n+5] , c[n+5];
v[0] = c[0] = 0;
for(int i = 0 ; i < n ; i ++){
v[i+1]=v[i];
c[i+1]=c[i];
if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u'){
v[i+1]++;
}else{
c[i+1]++;
}
}
int ans = 0;
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j <= i ; j ++){
int x = v[i+1]-v[j] , y = c[i+1]-c[j];
if(x == y && ((x * y) % k == 0))ans ++;
}
}
return ans;
}
};
交换得到字典序最小的数组
分段排序后排序,难在模拟
class Solution {
public:
vector<int> lexicographicallySmallestArray(vector<int>& nums, int limit) {
//第一部分排序
int n = nums.size();
vector<pair<int,int>>v;//每个点值,下标
for(int i = 0 ; i < n ; i ++)v.emplace_back(nums[i] , i);
sort(v.begin(),v.end());
//第二部分分段
vector<vector<pair<int,int>>>segs;//段
int last = -limit;
for(int i = 0 ; i < n ; i ++){ //v
if(v[i].first - last > limit)segs.push_back({});//新段
segs.back().push_back(v[i]);
last = v[i].first;
}
//第三部分回填
vector<int>ans(n);
for(auto &seg : segs){
vector<int> pos;
for (auto &p : seg) pos.push_back(p.second);//取所有下标排序
sort(pos.begin(), pos.end());
for (int i = 0; i < seg.size(); i++) ans[pos[i]] = seg[i].first;
}
return ans;
}
};
统计美丽子字符串 II
前缀和+哈希
class Solution {
public:
long long beautifulSubstrings(string s, int K) {
// 判断字符 c 是不是元音
auto check = [&](char c) {
return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
};
int n = s.size();
long long ans = 0;
// det:前缀中元音减辅音的值
// cnt:前缀中元音的数量
//mp[d]表示den值为d的数量
//mp[d][p]表示m[d]且cnt%k=p的数量
unordered_map<int, unordered_map<int, int>> mp;
// 用长度为 0 的前缀初始化哈希表
mp[0][0] = 1;
//0 = (cntr - cntl)^2%k = ((cntr-cntl)%k)^2 % k -->(w)^2 % k
//(cntr-cntl)%k=w , cntl %k = (cntr-w) % k
// valid 里保存了所有满足 w^2 mod k = 0 的 w
vector<int> valid;
for (int rem = 0; rem < K; rem++) if (rem * rem % K == 0) valid.push_back(rem);
int det = 0, cnt = 0;
// 枚举子串右端点
for (int i = 0; i < n; i++) {
if (check(s[i])) det++, cnt++;
else det--;
// 枚举 w
for (int rem : valid) {
int t = (cnt - rem + K) % K; //(cntr-w) % k
if (mp[det].count(t)) ans += mp[det][t];
}
// 用以 i 为结尾的前缀更新哈希表
mp[det][cnt % K]++; //mp[det][cntr%k]
}
return ans;
}
};