50.数组中重复出现的数字
知识点:数组;Set的不可重复性
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
解法一:
直接使用暴力查找,从头开始遍历,查找相同的元素
public class Solution(){
public int duplicate(int[] numbers){
int count = 1;
for(int i = 0; i < numbers.length; i++){
for(int j = i+1; j < numbers.length; j++){
if(numbers[i] == numbers[j]){
return numbers[i];
}
}
}
return -1;
}
}
时间复杂度O(n^2);
解法二:
数组的元素范围是0到n-1的时候,可以将值为i的元素调整到i的位置上去,如果在调整的时候发现,i这个位置上已经有了一个值为i的元素,那就可以知道i是重复的。
具体可查看下面的动图演示,很清楚明了。
动图演示
public class Solution(){
public int duplicate(int[] numbers){
for(int i = 0; i < numbers.length; i++){
while(numbers[i] != i){
if(numbers[i] == numbers[numbers[i]]){
return numbers[i]; //这句就是在控制如果在交换的过程中发现那个位置上已经有了一个值为i的元素,那就可以直接返回了;
}
swap(numbers, i);
}
}
return -1;
}
private void swap(int[] nums,int i){
int j = nums[i];
nums[i] = nums[j];
nums[j] = j;
}
}
时间复杂度O(n);
解法三:
当遇到这种找重复的时候第一时间应该想到什么,没错,就是Java中的set,Java中的Set的最大特点就是无序不可重复。所以可以将数组中的元素全部放到Set里去处理,然后就可以直接用Set的contain方法。
public class Solution(){
public int duplicate(int[] numbers){
Set<Integer> set = new HashSet<Integer>();
for(int i : numbers){
if(set.contains(i)){
return i; //如果包含则直接返回,不包含将其添加到set里;
}else{
set.add(i);
}
}
return -1;
}
}
时间复杂度O(n);