Maximum Difference Between Even and Odd Frequency II
Maximum Difference Between Even and Odd Frequency II
You are given a string s
and an integer k
. Your task is to find the maximum difference between the frequency of two characters, freq[a] - freq[b]
, in a substring subs
of s
, such that:
subs
has a size of at leastk
.- Character
a
has an odd frequency insubs
. - Character
b
has an even frequency insubs
.
Return the maximum difference.
Note that subs
can contain more than 2 distinct characters.
Example 1:
Input: s = "12233", k = 4
Output: -1
Explanation:
For the substring "12233"
, the frequency of '1'
is 1 and the frequency of '3'
is 2. The difference is 1 - 2 = -1
.
Example 2:
Input: s = "1122211", k = 3
Output: 1
Explanation:
For the substring "11222"
, the frequency of '2'
is 3 and the frequency of '1'
is 2. The difference is 3 - 2 = 1
.
Example 3:
Input: s = "110", k = 3
Output: -1
Constraints:
3 <= s.length <= 3 * 104
s
consists only of digits'0'
to'4'
.- The input is generated that at least one substring has a character with an even frequency and a character with an odd frequency.
1 <= k <= s.length
解题思路
一开始想的做法太复杂了,赛时没做出来,赛后磨了快一个小时才过。
关键是要想到,对于任意一段子串,必然会选出一个出现频率是奇数的数字 ,以及出现频率是偶数的数字 。观察到数字范围非常小只有 ,意味着我们可以暴力枚举 和 。对于 的子串,答案为 ,其中 ,。该式子可以等价为 ,因此我们可以枚举右端点 ,然后快速得到满足条件的左端点 关于 的最大值。
另外在 中由于 要出现奇数次, 要出现偶数次,因此 的奇偶性要与 不同, 的奇偶性要与 相同。为此定义 表示在满足条件的 中, 是奇/偶, 是奇/偶时,关于 的最大值。
下面考虑 应该满足什么条件。首先由于子串的长度至少为 ,因此有 。另外由于区间内必须要出现 和 ,因此有 且 。注意到 和 随着 递增而递增,因此满足条件的 实际上是一个前缀,且随着 递增而往右扩展。因此我们可以用一个指针来维护这个前缀的右端点,同时维护这个前缀中的 。
因此对于右端点为 且选择 和 分别作为出现奇数和偶数的数字的子串中,最大的答案是 。
AC 代码如下,时间复杂度为 :
class Solution {
public:
int maxDifference(string s, int k) {
int n = s.size();
int ret = -0x3f3f3f3f;
for (int a = 0; a <= 4; a++) {
for (int b = 0; b <= 4; b++) {
vector<int> s1(n + 1), s2(n + 1);
for (int i = 1; i <= n; i++) {
s1[i] = s1[i - 1] + (s[i - 1] - '0' == a);
s2[i] = s2[i - 1] + (s[i - 1] - '0' == b);
}
vector<vector<int>> g(2, vector<int>(2, -0x3f3f3f3f));
for (int i = k, j = 0; i <= n; i++) {
while (i - j >= k && s1[i] > s1[j] && s2[i] > s2[j]) {
g[s1[j] & 1][s2[j] & 1] = max(g[s1[j] & 1][s2[j] & 1], s2[j] - s1[j]);
j++;
}
ret = max(ret, s1[i] - s2[i] + g[~s1[i] & 1][s2[i] & 1]);
}
}
}
return ret;
}
};
参考资料
子集状压 DP【力扣周赛 435】:https://www.bilibili.com/video/BV1D5F6eRECp/
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/18697111
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2023-02-02 Minimum Cost to Make Array Equal
2023-02-02 Count Increasing Quadruplets
2023-02-02 方程的解