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
解题思路
一开始想的做法太复杂了,赛时没做出来,赛后磨了快一个小时才过。
关键是要想到,对于任意一段子串,必然会选出一个出现频率是奇数的数字 $a$,以及出现频率是偶数的数字 $b$。观察到数字范围非常小只有 $0 \sim 4$,意味着我们可以暴力枚举 $a$ 和 $b$。对于 $[l, r]$ 的子串,答案为 $sa_r - sa_{l-1} - \left(sb_r - sb_{l-1}\right)$,其中 $sa_i = \sum\limits_{j=1}^{i}{[s_j = a]}$,$sb_i = \sum\limits_{j=1}^{i}{[s_j = b]}$。该式子可以等价为 $sa_r - sb_r + sb_{l-1} - sa_{l-1}$,因此我们可以枚举右端点 $r$,然后快速得到满足条件的左端点 $l$ 关于 $sb_{l-1} - sa_{l-1}$ 的最大值。
另外在 $[l,r]$ 中由于 $a$ 要出现奇数次,$b$ 要出现偶数次,因此 $sa_{l-1}$ 的奇偶性要与 $sa_r$ 不同,$sb_{l-1}$ 的奇偶性要与 $sb_r$ 相同。为此定义 $g(0/1,0/1)$ 表示在满足条件的 $l$ 中,$sa_{l-1}$ 是奇/偶,$sb_{l-1}$ 是奇/偶时,关于 $sb_{l-1} - sa_{l-1}$ 的最大值。
下面考虑 $l$ 应该满足什么条件。首先由于子串的长度至少为 $k$,因此有 $r - l + 1 \geq k$。另外由于区间内必须要出现 $a$ 和 $b$,因此有 $sa_r - sa_{l-1} > 0$ 且 $sb_r - sb_{l-1} > 0$。注意到 $sa_r$ 和 $sb_r$ 随着 $r$ 递增而递增,因此满足条件的 $l$ 实际上是一个前缀,且随着 $r$ 递增而往右扩展。因此我们可以用一个指针来维护这个前缀的右端点,同时维护这个前缀中的 $g(0/1,0/1)$。
因此对于右端点为 $r$ 且选择 $a$ 和 $b$ 分别作为出现奇数和偶数的数字的子串中,最大的答案是 $sa_r - sb_r + g(\neg (sa_r \bmod{2}), sb_r \bmod{2})$。
AC 代码如下,时间复杂度为 $O(4^2 n)$:
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