找出数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
示例 1:
输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3
限制:
2 <= n <= 100000
思路1
做双重循环,标记第一个元素,往后遍历,若重复则输出。
代码如下:
class Solution {
public int findRepeatNumber(int[] nums) {
int n;
int count = 0;
int num=-1;
for(int i = 0;i<nums.length;i++){
for(int j = i+1;j<nums.length;j++){
n=nums[i];
if(nums[i]==nums[j]) {
num=nums[i];
count++;
break;
}
}
}
return num;
}
}
显然,leetcode给出的测试数组过长,时间复杂度O(n2)显然会超过时间限制,弃之。
思路2(原地交换法)
由于数组内的数字已经有限制为0~n-1,且数组内存在重复数字,说明数组并未被充分利用。因此可以对不在自己顺序位置上的元素进行交换,若同一位置出现两个相同元素,则说明出现了重复元素。
if(nums[i] == nums[nums[i]]){
flag = nums[i];
break;
}
完整代码如下:
class Solution {
public int findRepeatNumber(int[] nums) {
int flag=-1;
int i=0;
while(i < nums.length){
if(nums[i] == i){
i++;
continue;
}
if(nums[i] == nums[nums[i]]){
flag = nums[i];
break;
}
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
if(flag == -1) return -1;
else return flag;
}
}
思路3(利用哈希表的特点)
使用哈希表(Set)记录数组的各个数字,当查找到重复数字则直接返回。
代码如下:
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> dic = new HashSet<>();
for(int num : nums) {
if(dic.contains(num)) return num;
dic.add(num);
}
return -1;
}
}