0. 前言
1. 题解
1.1 5368. 找出数组中的幸运数(1394. Find Lucky Integer in an Array)
class Solution {
public:
int findLucky(vector<int>& arr) {
int len = arr.size();
map<int, int> cnt;
for (auto v : arr) {
cnt[v]++;
}
int ans = -1;
for (auto it = cnt.begin() ; it != cnt.end() ; it++) {
if (it->first == it->second) {
ans = it->first;
}
}
return ans;
}
};
1.2 5369. 统计作战单位数(1395. Count Number of Teams)
class Solution {
public:
int numTeams(vector<int>& rating) {
int n = rating.size();
int ans = 0;
if (n < 3) return 0;
for (int i = 1 ; i < n-1 ; i++) {
int ll = 0, ls = 0, rl = 0, rs = 0;
for (int j = 0 ; j < i ; j++) {
if (rating[j] < rating[i]) {
ls++;
} else if (rating[j] > rating[i]) {
ll++;
}
}
for (int j = i+1 ; j < n ; j++) {
if (rating[j] < rating[i]) {
rs++;
} else if (rating[j] > rating[i]) {
rl++;
}
}
ans += ls * rl + ll * rs;
}
return ans;
}
};
1.3 5370. 设计地铁系统(1396. Design Underground System)
class UndergroundSystem {
public:
unordered_map<int, pair<string, int>> passenger;
unordered_map<string, unordered_map<string, pair<int, int>>> startEnd;
UndergroundSystem() {
}
void checkIn(int id, string stationName, int t) {
passenger[id] = make_pair(stationName, t);
}
void checkOut(int id, string stationName, int t) {
string start = passenger[id].first;
if (startEnd[start].find(stationName) == startEnd[start].end()) {
startEnd[start][stationName] = make_pair(t-passenger[id].second, 1);
} else {
startEnd[start][stationName].first += t-passenger[id].second;
startEnd[start][stationName].second += 1;
}
}
double getAverageTime(string startStation, string endStation) {
return (double)startEnd[startStation][endStation].first / (double)startEnd[startStation][endStation].second;
}
};
/**
* Your UndergroundSystem object will be instantiated and called as such:
* UndergroundSystem* obj = new UndergroundSystem();
* obj->checkIn(id,stationName,t);
* obj->checkOut(id,stationName,t);
* double param_3 = obj->getAverageTime(startStation,endStation);
*/
1.4 5371. 找到所有好字符串(1397. Find All Good Strings)
- 中文版题目描述:https://leetcode-cn.com/classic/problems/find-all-good-strings/description/
- 英文版题目描述:https://leetcode.com/problems/find-all-good-strings/description/
- 思路:数位 DP + KMP:
- 数位 DP 问题往往都是这样的题型,给定一个闭区间 [l, r],让你求这个区间中满足某种条件的数的总数
- 首先我们将问题转化成更加简单的形式,设 f[i] 表示在区间 [1,i] 中满足条件的数的数量,那么所求的答案就是 f[r] - f[l-1]
- 数位 dp 中,dp 数组永远为 dp[i][state][eq]
- 其中,i 表示前 i 位,即为结果字符串的前缀
- state 描述前缀的状态
- eq 表示前缀是否与 s[0,i) 相等
- dp[i][state][eq] 就是有多少个长度为 i 的前缀,其状态为 state 且相等状态等于 eq
- 在本题中,state 表示前缀与 evil 字符串匹配的最长长度
- 初始化 dp[0][*][1],当长度为 0、匹配长度为0 时,只有 dp[0][0][1] = 1,其它位置都为 0
- 当前匹配 state 长度后,增加一个字符 cur,与 evil 字符串匹配的最大长度怎么计算,根据 kmp 的 next 数组计算即可
- 每次通过 dp[i] 扩展 dp[i+1] 的状态,具体情况可以分为,通过 dp[i][state][0](前缀长期为 i 且小于 s[i:])、dp[i][state][1](前缀长期为 i 且等于 s[i:])扩展出 dp[i+1][ns][0] 和 dp[i+1][ns][1] 等状态
- 其中 ns 为 state 通过 next 数组在添加一个字符 cur 后的最大前缀匹配长度
- 代码如下:
class Solution {
public:
vector<int> getNextArray(string pattern) {
int len = pattern.length();
vector<int> res(len+1,0);
int j = 0;
for (int i = 1 ; i < len ; i++) {
while (j && pattern[i] != pattern[j]) j = res[j];
if (pattern[i] == pattern[j]) j++;
res[i+1] = j;
}
return res;
}
int getNextState(int state, vector<int>& next, string pattern, char cur) {
int j = state;
while (j > 0 && pattern[j] != cur) j = next[j];
if (pattern[j] == cur) j++;
return j;
}
bool dec(int n, string& s) {
bool result = false;
for (int i = n-1 ; i >= 0 ; i--) {
if (s[i] > 'a') {
s[i]--;
result = true;
break;
} else {
s[i] = 'z';
}
}
return result;
}
long long dfs(int n, string s, vector<int>& next, string pattern) {
long long mod = (long long)1000000007;
int lp = pattern.length();
vector<vector<vector<long long>>> dp = vector<vector<vector<long long>>>(n+1, vector<vector<long long>>(lp+1, vector<long long>(2, 0)));
dp[0][0][1] = 1;
for (int i = 0 ; i < n ; i++) {
for (int j = 0 ; j < lp ; j++) {
int ns = getNextState(j, next, pattern, s[i]);
dp[i+1][ns][1] = (dp[i+1][ns][1] + dp[i][j][1]) % mod;
for (char k = 'a' ; k <= 'z' ; k++) {
ns = getNextState(j, next, pattern, k);
dp[i+1][ns][0] = (dp[i+1][ns][0] + dp[i][j][0]) % mod;
}
for (char k = 'a' ; k < s[i] ; k++) {
ns = getNextState(j, next, pattern, k);
dp[i+1][ns][0] = (dp[i+1][ns][0] + dp[i][j][1]) % mod;
}
}
}
long long result = (long long)0;
for (int i = 0 ; i < lp ; i++) {
result = (result + dp[n][i][0]) % mod;
result = (result + dp[n][i][1]) % mod;
}
return result;
}
int findGoodStrings(int n, string s1, string s2, string evil) {
vector<int> next = getNextArray(evil);
bool flag = dec(n, s1);
long long ans = (long long)0;
if (flag) {
ans = dfs(n, s2, next, evil) - dfs(n, s1, next, evil);
} else {
ans = dfs(n, s2, next, evil);
}
if (ans < 0) {
ans += (long long)1000000007;
}
return (int)ans;
}
};
2. 参考文献