力扣 - 剑指 Offer 03. 数组中重复的数字
题目
思路1(哈希表)
- 依次遍历数组,将元素存入哈希表中,如果哈希表中已经存在,那么就找到重复的数
代码
class Solution {
public int findRepeatNumber(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int n : nums) {
if (!set.add(n)) {
return n;
}
}
return -1;
}
}
复杂度分析
- 时间复杂度:\(O(N)\)
- 空间复杂度:\(O(N)\)
思路2(原地交换)
- 由于数组是无序的,我们可以遍历数组,将数组的值放到对应的索引位置上,与它进行交换
- 当出现索引位置上的值已经有序,而当前的数字又需要放到该位置上,因此冲突,就找到了重复的值
- 例如:
[2, 3, 1, 0, 2, 5, 3]:2不等于当前索引值0,因此放到索引2上,然后将位置的1放到当前位置,此时:[1, 3, 2, 0, 2, 5, 3]- 因为
1还是不等于当前索引值0,所以将1与3交换,此时:[3, 1, 2, 0, 2, 5, 3] - 因为
3又不等于索引值0,所以将3与0进行交换,此时:[0, 1, 2, 3, 2, 5, 3] - 然后
0等于索引0,然后下一个1也等于索引值1、2也等于索引值2、3也等于索引值3 - 接下来到了第五个数字,
2不等于索引值4,所以要放到索引为2的位置上,但是,此时索引2位置上已经是正确的2了,因此可以知道该数字重复了 - 最后找到重复的数字2了~
代码
class Solution {
public int findRepeatNumber(int[] nums) {
int length = nums.length;
int index = 0;
while (index < length) {
// 如果索引和数组的值相等才进行后一位的调整
if (nums[index] == index) {
index++;
continue;
}
// 能到这里说明当前的值不在对应的索引位置上,但是如果对应的索引位置上已经存在了值,就说明该数字重复了
if (nums[nums[index]] == nums[index]) {
return nums[index];
}
// 将当前位置的值放到对应的索引位置进行交换
int afterIndex = nums[index];
nums[index] = nums[afterIndex];
nums[afterIndex] = afterIndex;
}
return -1;
}
}
复杂度分析
- 时间复杂度:\(O(N)\),只需遍历一次数组
- 空间复杂度:\(O(1)\),在原数组操作,不需要额外的空间
我走得很慢,但我从不后退!

浙公网安备 33010602011771号