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 least k.
  • Character a has an odd frequency in subs.
  • Character b has an even frequency in subs.

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/

posted @ 2025-02-02 21:33  onlyblues  阅读(105)  评论(0)    收藏  举报
Web Analytics