题目来源于力扣(LeetCode)
一、题目
题目相关标签:哈希表
提示:
4 <= A.length <= 10000
0 <= A[i] < 10000
A.length
为偶数
二、解题思路
2.1 Set 方式
-
据题意:2N 个长度的数组中,有 N + 1 个不同元素,且有一个元素重复了 N 次
即 2 * 3 个长度的数组中,有 4 个不同的元素,有一个元素重复了 3 次
-
说明数组中有且仅有一个重复的元素
-
那么通过遍历数组,Set 集合存储数组中的元素
-
遍历过程中判断遍历元素是否存在于 Set 中,若存在则说明元素重复
-
不存在则将当前遍历元素存储到 Set 中
2.2 比较法
-
据题意:2N 个长度的数组中,有 N + 1 个不同元素,且有一个元素重复了 N 次
即 2 * 3 个长度的数组中,有 4 个不同的元素,有一个元素重复了 3 次
-
说明数组中有且仅有一个重复的元素
-
经题意分析及用例判断,得知:2N 个长度的数组中,有 N + 1 个不同元素的情况下,连续的 4 个元素组成的子数组中必定有两个重复的元素出现
-
那么设置比较元素的间隔,分别为 1,2,3
-
通过循环对数组中的元素与间隔的元素进行比较,相同时即重复,返回结果
三、代码实现
3.1 Set 方式
public static int repeatedNTimes(int[] A) {
int[] nums = A;
Set<Integer> set = new HashSet<>();
for (int i : nums) {
if (set.contains(i)) {
return i;
}
set.add(i);
}
return -1;
}
3.2 比较法
public static int repeatedNTimes2(int[] A) {
int[] nums = A;
// 当前元素的后三位之内必有重复元素
// 例如:{9, 5, 6, 9},重复元素两个 9 之间,差3位
// 外层循环:间隔的数量
// 间隔 1 时,内层循环完成未找到重复元素,间隔 2 再找,再未找到时,间隔 3 找
for (int i = 1; i <= 3; i++) {
// 内层循环:遍历数组
for (int j = 0; j < nums.length - i; j++) {
if (nums[j] == nums[j + i]) {
return nums[j];
}
}
}
return -1;
}
四、执行用时
4.1 Set 方式
4.2 比较法
五、部分测试用例
public static void main(String[] args) {
int[] nums = {1, 2, 3, 3}; // output: 3
// int[] nums = {2, 1, 2, 5, 3, 2}; // output: 2
// int[] nums = {5, 1, 5, 2, 5, 3, 5, 4}; // output: 5
int result = repeatedNTimes(nums);
System.out.println(result);
}