Kimi LeetCode 3445. 奇偶频次间的最大差值 II Python3实现
这道题的核心思路是:枚举字符对 + 滑动窗口 + 前缀奇偶状态压缩。
由于字符串 `s` 仅由 `'0'``'4'` 组成,最多只有 5 种字符,因此可以枚举所有 `(a, b)` 对(`a` 为奇数次字符,`b` 为偶数次字符),最多 5 \times 4 = 20 种。
对于固定的 `(a, b)`,设前缀 `[0, i]` 中 `a` 的个数为 `A[i]`,`b` 的个数为 `B[i]`。子串 `[l, r]` 的差值为:
(A[r] - A[l-1]) - (B[r] - B[l-1]) = (A[r] - B[r]) - (A[l-1] - B[l-1])
要最大化该值,对于每个 `r`,需要找到满足以下条件的最小 `A[l-1] - B[l-1]`:
- 子串长度 \ge k
- `A[r] - A[l-1]` 为奇数(`a` 出现奇数次)
- `B[r] - B[l-1]` 为非零偶数(`b` 出现偶数次且至少 2 次)
由于只关心奇偶性,用 `best[pa][pb]` 记录前缀中 `a` 的奇偶性为 `pa`、`b` 的奇偶性为 `pb` 时,`A - B` 的最小值。通过滑动窗口维护合法左端点,时间复杂度 O(20 \times n)。
```python
class Solution:
def maxDifference(self, s: str, k: int) -> int:
n = len(s)
ans = -10**9
for a in range(5):
for b in range(5):
if a == b:
continue
# best[pa][pb]: 前缀中 a 的奇偶性为 pa, b 的奇偶性为 pb 时,
# pre_a - pre_b 的最小值
best = [[10**9] * 2 for _ in range(2)]
cnt_a = cnt_b = 0 # 右端点前缀计数
pre_a = pre_b = 0 # 左端点前缀计数
left = -1
for right in range(n):
cnt_a += (int(s[right]) == a)
cnt_b += (int(s[right]) == b)
# 移动左指针,将满足条件的左端点加入 best
# 条件:长度 >= k,且子串中 b 至少出现 2 次(保证偶数且非零)
while right - left >= k and cnt_b - pre_b >= 2:
pa = pre_a & 1
pb = pre_b & 1
best[pa][pb] = min(best[pa][pb], pre_a - pre_b)
left += 1
pre_a += (int(s[left]) == a)
pre_b += (int(s[left]) == b)
# 查询:需要左端点 a 的奇偶性相反,b 的奇偶性相同
ra = cnt_a & 1
rb = cnt_b & 1
if best[ra ^ 1][rb] < 10**9:
ans = max(ans, cnt_a - cnt_b - best[ra ^ 1][rb])
return ans
```
复杂度分析:
- 时间复杂度:O(20 \times n) = O(n),其中 n = \text{len}(s)
- 空间复杂度:O(1),仅使用常数个变量和 2 \times 2 的数组
更多推荐

所有评论(0)