Kimi LeetCode 3445. 奇偶频次间的最大差值 II Rust实现
这是 LeetCode 3445. 奇偶频次间的最大差值 II 的 Rust 实现。
解题思路
核心观察:字符串 `s` 仅由 `'0'``'4'` 组成,因此最多只有 5 种字符。可以暴力枚举所有字符对 `(a, b)`(`a` 为奇数频次,`b` 为偶数频次且非零),共 `5×4=20` 种组合。
问题转化:对于固定的 `(a, b)`,把 `a` 视为 `+1`,`b` 视为 `-1`,其余视为 `0`。问题转化为找一个长度至少为 `k` 的子数组,使得:
- `+1` 出现 奇数 次
- `-1` 出现 非零偶数 次
- 最大化子数组和(即 `freq[a] - freq[b]`)
滑动窗口 + 前缀状态压缩:
- 用前缀和记录 `a` 和 `b` 的累计出现次数
- 状态 `state = (cnt_a % 2) << 1 | (cnt_b % 2)`,只有 4 种状态
- 维护每种状态下最小的 `pre_a - pre_b`,使得后续查询时可以最大化 `(cur_a - cur_b) - (pre_a - pre_b)`
- 收缩左边界时确保子串中 `b` 至少出现 2 次(`cur_b - pre_b >= 2`),从而保证非零偶数
Rust 代码
```rust
impl Solution {
pub fn max_difference(s: String, k: i32) -> i32 {
let n = s.len();
let s_bytes = s.as_bytes();
let mut ans = i32::MIN;
let k = k as i32;
// 枚举奇数频次字符 a 和偶数频次字符 b(a ≠ b)
// s 仅由 '0'~'4' 组成,最多 5×4=20 种组合
for a in b'0'..=b'4' {
for b in b'0'..=b'4' {
if a == b {
continue;
}
// best[state] 记录状态 state 下最小的 (pre_a - pre_b)
// state = (pre_a % 2) << 1 | (pre_b % 2),取值 0~3
let mut best = [i32::MAX; 4];
let mut cur_a = 0i32; // 前缀 [0..r] 中 a 的个数
let mut cur_b = 0i32; // 前缀 [0..r] 中 b 的个数
let mut pre_a = 0i32; // 前缀 [0..l] 中 a 的个数
let mut pre_b = 0i32; // 前缀 [0..l] 中 b 的个数
let mut l = -1i32; // 左边界在 a、b 计数数组中的索引(前缀长度)
for r in 0..n {
let c = s_bytes[r];
if c == a {
cur_a += 1;
} else if c == b {
cur_b += 1;
}
// 收缩左边界,同时记录合法左端点的最小前缀差
// 条件:
// 1. 子串长度 >= k:r - l >= k
// 2. 子串中 b 至少出现 2 次(保证非零偶数):cur_b - pre_b >= 2
// 3. 子串中 a 至少出现 1 次(配合奇偶性即为奇数):cur_a - pre_a >= 1
while (r as i32 - l) >= k && (cur_b - pre_b) >= 2 && (cur_a - pre_a) >= 1 {
let state = (((pre_a & 1) << 1) | (pre_b & 1)) as usize;
best[state] = best[state].min(pre_a - pre_b);
l += 1;
let lc = s_bytes[l as usize];
if lc == a {
pre_a += 1;
} else if lc == b {
pre_b += 1;
}
}
// 查询:需要子串中 a 为奇数、 b 为偶数
// 即 pre_a % 2 != cur_a % 2,pre_b % 2 == cur_b % 2
let need_state = ((((cur_a & 1) ^ 1) << 1) | (cur_b & 1)) as usize;
if best[need_state] != i32::MAX {
ans = ans.max(cur_a - cur_b - best[need_state]);
}
}
}
}
ans
}
}
```
复杂度分析
- 时间复杂度:`O(20 × n) = O(n)`,其中 `n = s.len()`。20 是字符对的枚举数,每种组合内是线性滑动窗口。
- 空间复杂度:`O(1)`,只使用了常数个变量和长度为 4 的 `best` 数组。
下载链接
[LeetCode 3445 Rust 实现](sandbox:///mnt/agents/output/leetcode_3445.rs)

更多推荐


所有评论(0)