news 2026/8/17 20:13:50

千问 LeetCode 3934. 最短唯一子数组 Rust实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
千问 LeetCode 3934. 最短唯一子数组 Rust实现

核心思路

1. 二分答案:若长度 len 存在唯一子数组,则 len+1 也必然存在(子数组越长越不容易重复),满足单调性。
2. 双模数前缀哈希:用两组不同的 base/mod 计算子数组哈希,拼成 (u64, u64) 元组作为唯一标识,O(1) 比较子数组。
3. 统计频次:对每个候选长度,统计所有子数组哈希出现次数,若存在仅出现 1 次的即为可行。

Rust 实现

use std::collections::HashMap;

impl Solution {
const MOD1: u64 = 1_000_000_007;
const MOD2: u64 = 998_244_353;
const BASE1: u64 = 131;
const BASE2: u64 = 13331;

pub fn smallest_unique_subarray(nums: Vec<i32>) -> i32 {
let n = nums.len();
if n == 1 {
return 1;
}

// 预处理前缀哈希与幂次
let mut pre1 = vec![0u64; n + 1];
let mut pre2 = vec![0u64; n + 1];
let mut pw1 = vec![1u64; n + 1];
let mut pw2 = vec![1u64; n + 1];

for i in 0..n {
// nums[i] 可能为负数,需要加 mod 保证非负
let v = (nums[i] % Self::MOD1 as i32 + Self::MOD1 as i32) as u64;
pre1[i + 1] = (pre1[i] * Self::BASE1 + v) % Self::MOD1;

let v2 = (nums[i] % Self::MOD2 as i32 + Self::MOD2 as i32) as u64;
pre2[i + 1] = (pre2[i] * Self::BASE2 + v2) % Self::MOD2;

pw1[i + 1] = pw1[i] * Self::BASE1 % Self::MOD1;
pw2[i + 1] = pw2[i] * Self::BASE2 % Self::MOD2;
}

// 获取区间 [i, i+len) 的哈希值
let get_hash = |pre: &[u64], pw: &[u64], i: usize, len: usize, modulus: u64| -> u64 {
let h = (pre[i + len] + modulus - pre[i] * pw[len] % modulus) % modulus;
h
};

// 检查是否存在唯一的子数组
let has_unique = |length: usize| -> bool {
let mut cnt: HashMap<(u64, u64), i32> = HashMap::new();
for i in 0..=(n - length) {
let h1 = get_hash(&pre1, &pw1, i, length, Self::MOD1);
let h2 = get_hash(&pre2, &pw2, i, length, Self::MOD2);
*cnt.entry((h1, h2)).or_insert(0) += 1;
}
cnt.values().any(|&v| v == 1)
};

// 二分最小长度
let (mut lo, mut hi, mut ans) = (1usize, n, n);
while lo <= hi {
let mid = (lo + hi) / 2;
if has_unique(mid) {
ans = mid;
if mid == 0 { break; }
hi = mid - 1;
} else {
lo = mid + 1;
}
}
ans as i32
}
}

关键点解析

- 前缀哈希公式:hash[i..i+len) = (pre[i+len] - pre[i] × base^len + MOD) % MOD,O(1) 计算任意子数组哈希。加 MOD 是为了防止减法产生负数。
- 负数处理:nums[i] 可能为负数,计算哈希前先 (nums[i] % MOD + MOD) % MOD 保证非负。
- 双哈希元组:Rust 原生支持 (u64, u64) 作为 HashMap 的 key(实现了 Hash + Eq),无需手动拼接。
- 二分单调性:长度越大,子数组越独特,"存在唯一子数组"这一性质单调递增。
- 时间复杂度:O(n log n),二分 O(log n) 轮,每轮 O(n) 遍历 + HashMap 操作。
- 空间复杂度:O(n),存储前缀哈希、幂次数组和 HashMap。

示例验证

nums = [1,1,2,2,1]:
- 长度 1:1 出现 3 次,2 出现 2 次 → 无唯一
- 长度 2:[1,1]、[1,2]、[2,2]、[2,1] 各出现 1 次 → 有唯一 ✅
- 二分得答案 2

需要我把这道题的 TypeScript 版本也补上吗?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/17 20:11:29

标致508高性能概念车设计解析:从概念到量产的技术预演

1. 从“官图”到“概念”&#xff1a;一次设计语言的极限预演看到“日内瓦首发 标致508高性能概念车官图”这个标题&#xff0c;我第一反应是&#xff0c;这绝不仅仅是一次新车预告。对于熟悉汽车行业&#xff0c;尤其是对法系车设计有长期观察的人来说&#xff0c;这更像是一场…

作者头像 李华
网站建设 2026/8/17 20:04:21

微信聊天记录导出全攻略:三步搞定永久保存与年度聊天报告

微信聊天记录导出全攻略&#xff1a;三步搞定永久保存与年度聊天报告 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/We…

作者头像 李华
网站建设 2026/8/17 20:03:55

3DS游戏格式转换怎么省心?用3dsconv把.3ds变成可安装的CIA

3DS游戏格式转换怎么省心&#xff1f;用3dsconv把.3ds变成可安装的CIA 【免费下载链接】3dsconv Python script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format 项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv 你刚…

作者头像 李华