题目链接:https://leetcode.cn/problems/sum-of-beauty-of-all-substrings/
题目大意:定义字符串的【美丽值】为其中出现频率最高的字符的频率减去出现频率最低的字符频率,若字符串中出现的字符种类小于2个,那么美丽值为零(因为最高和最低是同一个字符)。给出一个字符串str
,求其所有子串的美丽值的和。
思路:暴力做肯定会超时,用前缀和pre[i][c]
来保存[0, i]
区间内字符c
出现的次数。为了方便计算区间差,我们使pre[][]
的第一维长度为N+1
,默认pre[0]
内保存的全都是0
,从pre[1]
开始保存str
内第一个字符的频率。
随后遍历,取所有长度大于等于2的子串(因为长度为1的话,美丽值必然是0),用区间差计算这个子串内某个字符的出现频率,统计出现频率最高和最低(仅当频率非零时它才是合法的),美丽值大于0时加入结果中。
完整代码:
class Solution {
public:
int beautySum(string s) {
int N = s.length();
vector<vector<int>> pre(N+1, vector<int>(26, 0));
for (int i = 1; i <= N; i++) {
int now = s[i-1] - 'a';
for (int c = 0; c < 26; c++)
pre[i][c] = pre[i-1][c];
pre[i][now]++;
}
int ret = 0;
for (int i = 1; i <= N; i++) {
for (int j = i+1; j <= N; j++) {
int most = 0, least = INT_MAX;
for (int c = 0; c < 26; c++) {
int tmp = pre[j][c] - pre[i-1][c];
if (tmp != 0) {
if (tmp > most)
most = tmp;
if (tmp < least)
least = tmp;
}
}
if (most > least)
ret += most - least;
}
}
return ret;
}
};