最直接有效的方式是用hashset边遍历边检查:遇到add()返回false就说明当前元素已存在,立即返回true;时间复杂度平均o(n),空间复杂度o(n),逻辑清晰、代码简洁。

最直接有效的方式是用 HashSet 边遍历边检查:遇到 add() 返回 false,就说明当前元素已存在,立即返回 true。
用 HashSet 判断(推荐)
利用 HashSet 不允许重复的特性,遍历时尝试添加元素,add() 方法返回 false 表示该元素已存在。
- 时间复杂度平均为 O(n),只需遍历一次
- 空间复杂度 O(n),适用于整数、字符串或正确重写 equals/hashCode 的对象
- 不改变原数组顺序,逻辑清晰、代码简洁
示例代码:
Set<integer> seen = new HashSet();
for (int num : array) {
if (!seen.add(num)) {
return true; // 发现重复
}
}
return false;</integer>
排序后比较相邻元素
先调用 Arrays.sort() 排序,再顺序扫描是否有连续相等的值。
- 空间开销小,不依赖额外集合
- 但会修改原数组顺序,且排序耗时 O(n log n)
- 适合内存受限、且允许改动输入的场景
注意:对原始 int[] 排序后,只需一次线性扫描即可判断。
布尔数组标记法(限值域范围)
仅适用于所有元素都在 [0, n-1] 范围内的情况(n 是数组长度)。
- 创建 boolean[n] visited,以元素值为下标做标记
- 若 visited[num] 已为 true,说明重复
- 速度快、空间固定,但超出范围会抛 ArrayIndexOutOfBoundsException
符号位标记法(原地、无额外空间)
适用于元素全为正整数、且范围严格在 [1, n] 内的 int 数组。
- 遍历中取 abs(num)-1 作下标,将对应位置数值取负作为“已访问”标记
- 若发现该位置已是负数,则 abs(num) 就是重复元素
- 不申请新空间,但必须允许修改原数组
这是真正意义上的空间 O(1) 解法,但使用条件较严。
其他如双重循环、indexOf/lastIndexOf 等方式时间复杂度为 O(n²),只适合极小数组或教学演示,实际项目中应避免。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











