题目描述
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
Input:
{2, 3, 1, 0, 2, 5}
Output:
2
解题思路
对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。
以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复:
代码
package test;
public class Test {
/*
* 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,
* 也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2, 3, 1, 0, 2, 5, 3},
* 那么对应的输出是重复的数字2或者3。
*/
/**
* 找到数组中一个重复的数字
* 返回-1代表无重复数字或者输入无效
*/
public int getDuplicate(int[] arr) {
// 检查数组输入无效
if (arr == null || arr.length <= 0) {
System.out.println("数组输入无效!");
return -1;
}
// 检查数字大小超出范围
for (int a : arr) {
if(!(a >= 0 && a<= arr.length - 1)){
System.out.println("数字大小超出范围!");
return -1;
}
}
// 检查重复数字
for(int i = 0 ; i < arr.length ; i++){
while(arr[i] != i){ // 循环判断:arr[i]是否在i的位置上
if(arr[i] == arr[arr[i]]){
return arr[i];
}
// 将值为arr[i]调整到arr[i]的位置上
int temp;
temp = arr[i];
arr[i] = arr[temp];
arr[temp] = temp;
}
}
System.out.println("数组中无重复数字!");
return -1;
}
// ==================================测试代码==================================
/**
*数组为null
*/
public void test1() {
System.out.print("test1:");
int[] a = null;
int dup = getDuplicate(a);
if (dup >= 0)
System.out.println("重复数字为:" + dup);
}
/**
*数组无重复数字
*/
public void test2() {
System.out.print("test2:");
int[] a = { 0, 1, 2, 3 };
int dup = getDuplicate(a);
if (dup >= 0)
System.out.println("重复数字为:" + dup);
}
/**
*数组数字越界
*/
public void test3() {
System.out.print("test3:");
int[] a = { 1, 2, 3, 4 };
int dup = getDuplicate(a);
if (dup >= 0)
System.out.println("重复数字为:" + dup);
}
/**
*数组带重复数字
*/
public void test4() {
System.out.print("test4:");
int[] a = {2, 3, 1, 0, 2, 5};
// int[] a = {1,2,4};
int dup = getDuplicate(a);
if (dup >= 0)
System.out.println("重复数字为:" + dup);
}
public static void main(String[] args) {
Test f = new Test();
f.test1();
f.test2();
f.test3();
f.test4();
}
}