题目描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。
请找出数组中任意一个重复的数字。
示例
输入: [2, 3, 1, 0, 2, 5, 3]
输出: 2 或 3
解法一:哈希表
思路:
使用哈希表记录每个数字出现的次数,当找到第一个重复数字时返回。
具体过程如下:
- 初始化一个哈希表。
- 遍历数组中的每个数字,如果哈希表中已经存在该数字,则返回该数字;否则将该数字存入哈希表中。
- 遍历结束后,如果返回的是 -1,则说明数组中没有重复数字。
时间复杂度为 O ( n ) O(n) O(n),其中 n 是数组的长度。
代码:(哈希表,时间复杂度 O ( n ) O(n) O(n))
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (set.contains(num)) {
return num;
}
set.add(num);
}
return -1;
}
}
解法二:数组原地置换
思路:
根据题目给定的条件,数字的范围在 0~n-1,因此我们可以将每个数字放到其对应的位置上,如果发现目标位置上已经存在了该数字,则说明存在重复数字,返回即可。
具体过程如下:
- 遍历数组中的每个数字,将数字 num 放到 nums[num] 的位置上。如果发现目标位置上已经存在了该数字 num,则说明存在重复数字,返回即可。
- 遍历结束后,如果返回的是 -1,则说明数组中没有重复数字。
时间复杂度为 O ( n ) O(n) O(n),其中 n 是数组的长度。
代码:(数组原地置换,时间复杂度 O ( n ) O(n) O(n))
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) {
while (nums[i] != i) {
if (nums[i] == nums[nums[i]]) {
return nums[i];
}
// 交换 nums[i] 和 nums[nums[i]]
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
}