题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2或者3。
public class FindDuplicate {
//方法1:排序O(nlogn)
public static boolean duplicate(int []numbers){
for (int i = 0; i < numbers.length; i++) {
if(numbers[i]<0||numbers[i]>numbers.length-1){
System.out.println("无效的测试用例");
return false;
}
}
Arrays.sort(numbers);
int result=0;
for (int i = 0; i < numbers.length-1; i++) {
if(numbers[i]==numbers[i+1]){//如果是重复元素,位置是相邻的;
result=numbers[i];
System.out.println("第一个重复的元素"+result);
return true;
}
}
return false;
}
//方法2:使用哈希表时间复杂度O(n),空间复杂度是O(n);
public static boolean duplicate2(int []numbers){
if (numbers == null || numbers.length == 0){
return false;
}
for (int i = 0; i < numbers.length; i++) {
if(numbers[i]<0||numbers[i]>numbers.length-1){
System.out.println("无效的测试用例");
return false;
}
}
Map<Integer,Integer> map=new HashMap<>();
int result=0;
for (int i = 0; i < numbers.length; i++) {
if(!map.containsValue(numbers[i])){//map中<i,numbers[i]>,如果map中不包含numbers[i]就添加
map.put(i,numbers[i]);
}else {
result=numbers[i];//map中包含,就是重复元素
System.out.println("重复元素为"+result);
return true;
}
}
return false;
}
//使用推荐做法,时间复杂度O(n)
/*情况1:numbers[i]==i,扫描下一个数字
* 情况2:numbers[i]!=i,eg:(numbers[4]=2)!=下标4
* then:numbers[i]和number[number[i]]比较,
* 如果相等,就有重复元素eg:numbers[4]=2,我们们要比较2这个位置上的元素是不是等于2
* 如果不相等:就交换 让numbers[i]回到下标和它相等的位置eg:numbers[0]=2,那么就让它和下标为2的元素交换
* */
//结果[0,1,2,3]//数值和下标是相等的
public static boolean duplicate3(int []numbers){
if(numbers==null||numbers.length==0){
return false;
}
for (int i = 0; i < numbers.length; i++) {
if(numbers[i]<0||numbers[i]>numbers.length-1){
System.out.println("无效的测试用例");
return false;
}
}
for (int i = 0; i < numbers.length; i++) {
int result=0;
while (numbers[i]!=i){ //我和我的下标不相等,我就要回到和我下标相等的位置
if(numbers[i]==numbers[numbers[i]]){//发现下标里面放的是和我一样的值,那么我就直接返回true
result=numbers[i];
System.out.println("重复的元素"+result);
return true;
}
int temp=numbers[i];//发现和我的值不一样,就要调换
numbers[i]=numbers[numbers[i]];
numbers[numbers[i]]=temp;
}
}
return false;
}
public static void main(String[] args) {
//包含一个或者多个的重复元素的数字
int[]numbers={2,3,1,0,2,5,3};
System.out.println(duplicate(numbers));
System.out.println(duplicate2(numbers));
System.out.println(duplicate3(numbers));
//数组中不包含重复数字
System.out.println("=========================");
int[]numbers2={2,3,1,0,4,5};
System.out.println(duplicate(numbers2));
System.out.println(duplicate2(numbers2));
System.out.println(duplicate3(numbers2));
//无效的测试用例
System.out.println("=========================");
int[]numbers3={-2,3,1,0,4,5,7};
System.out.println(duplicate(numbers3));
System.out.println(duplicate2(numbers3));
System.out.println(duplicate3(numbers3));
}
}
第一个重复的元素2
true
重复元素为2
true
重复的元素2
true
=========================
false
false
false
=========================
无效的测试用例
false
无效的测试用例
false
无效的测试用例
false