[Algo] 前缀和
1. 求arr所有子数组中累加和为aim的最长子数组长度
// 1. 求arr所有子数组中累加和为aim的最长子数组长度
// https://www.nowcoder.com/practice/36fb0fd3c656480c92b569258a1223d5
int f1(vector<int> &v, int aim)
{
unordered_map<int, int> m; // key: 前缀和, value: 最早出现的位置
m[0] = -1; // 前缀和为0已存在
int ans = 0, sum = 0;
for (int i = 0; i < v.size(); i++)
{
sum += v[i]; // 记录前缀和
int target = sum - aim;
if (m.find(target) != m.end()) ans = max(ans, i - m[target]);
if (m.find(sum) == m.end()) m[sum] = i;
}
return ans;
}
2. 求arr所有子数组中累加和为aim的子数组个数
// 2. 求arr所有子数组中累加和为aim的子数组个数
// https://leetcode.cn/problems/subarray-sum-equals-k/
int f2(vector<int> &v, int aim)
{
unordered_map<int, int> m; // key: 前缀和, value: 出现的次数
m[0] = 1; // 前缀和为0已存在
int ans = 0, sum = 0;
for (int i = 0; i < v.size(); i++)
{
sum += v[i]; // 记录前缀和
int target = sum - aim;
if (m.find(target) != m.end()) ans += m[target];
if (m.find(sum) != m.end()) m[sum]++;
else m[sum] = 1;
}
return ans;
}
3. 表现良好的最长时间段
// 3. 表现良好的最长时间段
// https://leetcode.cn/problems/longest-well-performing-interval/description/
int f3(vector<int> &v)
{
unordered_map<int, int> m; // key: 前缀和, value: 最早出现的位置
int ans = 0, sum = 0;
for (int i = 0; i < v.size(); i++)
{
sum += v[i] > 8 ? 1 : -1; // 记录前缀和
if (sum > 0) ans = i + 1; // (1) 前缀和大于0,直接更新
else if (m.find(sum - 1) != m.end()) ans = max(ans, i - m[sum - 1]); // (2) 否则找到第一次出现sum-1的位置
if (sum < 0 && m.find(sum) == m.end()) m[sum] = i;
}
return ans;
}
4. 每个元音包含偶数次的最长子字符串
// 4. 每个元音包含偶数次的最长子字符串
// https://leetcode.cn/problems/find-the-longest-substring-containing-vowels-in-even-counts/description/
int encode(char ch)
{
switch (ch)
{
case 'a': return 0;
case 'e': return 1;
case 'i': return 2;
case 'o': return 3;
case 'u': return 4;
default: return -1;
}
}
int f4(string &s)
{
int map[32]; // key: aeiou的奇偶性状态(1表示计数, 0表示偶数), value: 最早出现的位置
for (int i = 0; i < 32; i++) map[i] = -2; // -2表示状态没有出现过
map[0] = -1; // 00000已出现
int ans = 0, status = 0;
for (int i = 0; i < s.length(); i++)
{
if (encode(s[i]) != -1) status ^= 1 << encode(s[i]);
// status表示当前的奇偶性状态
if (map[status] != -2) ans = max(ans, i - map[status]);
else map[status] = i;
}
return ans;
}