题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
数据范围:0 <= n <= 10000
进阶:时间复杂度,空间复杂度
示例1
输入:[2,3,1,0,2,5,3]
返回值:2
说明:2或3都是对的
解法一:
思路:
1、对数组中的元素进行排序
2、遍历排序后的数组,如果当前元素和它的下一个位置的元素相同,说明该元素重复,即为所寻找的结果。因为题干要求只需找到重复数字之一即可。
代码:
import java.util.*;
public class Solution {
public int duplicate (int[] numbers) {
//处理特殊情况
if(numbers == null || numbers.length == 0){
return -1;
}
//先排序
Arrays.sort(numbers);
//存储结果
int ret = 0;
//遍历数组,如果当前元素和它的后一元素值相同,则即可要找的数
for(int i=0; i < numbers.length-1; i++){
if(numbers[i] == numbers[i+1]){
ret = numbers[i];
break;
}
}
return ret;
}
}
解法二:
思路:
利用map来存储数组中的元素。如果当前元素在map中已经存在,说明该元素重复,即找到结果。如果不在,则加入map中,继续遍历数组。
代码:
import java.util.*;
public class Solution {
public int duplicate (int[] numbers) {
//处理特殊情况
if(numbers == null || numbers.length == 0){
return -1;
}
//统计每个元素出现的次数
Map<Integer, Integer> map = new HashMap<>();
int ret = 0;
//遍历数组,如果当前元素已经在map中,说明该元素重复,返回该元素即可。如果不在,则添加map
for(int i=0; i < numbers.length; i++){
if(map.containsKey(numbers[i])){
ret = numbers[i];
break;
}else{
map.put(numbers[i], 1);
}
}
return ret;
}
}
感想:这类题在笔试或者面试中问到类似的,其实需要注意。因为之前我在面试一家公司的时候,笔试就出了这样一道题。我就是按照解法一写的。后来在面试完以后,那个面试官告诉我:这种题考验的是你对排序算法的掌握,而不是如何去找重复数字。当时我就一脸懵逼,但后来我给面试官讲了个快排,最后也拿到了这公司的offer。