编程思路:以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤。数组的第 0 个数字(从 0 开始计数,和数组的下标保持一致)是 2,与它的下标不相等,于是把它和下标为 2 的数字 1 交换。交换之后的数组是{1.3.2.0.2.5.3}。此时第 0 个数字是 1,仍然与它的下标不相等,继续把它和下标为 1 的数字 3 交换,得到数组{3,1,2,0,2,5,3}.接下来继续交换第 0 个数字 3 和第 3 个数字 0,得到数组{0,1,2,3,2,5,3}。此时第 0 个数字的数值为 0,接着扫描下一个数字。在接下来的几个数字中,下标为 1,2,3 的三个数字分别为 1,2,3 它们的下标和数值都分别相等,因此不需要做任何操作。接下来扫描到下标为 4 的数字 2。由于它的数值与它的下标不相等,再比较它和下标为 2 的数字。注意到此时数组中下标为 2 的数字也是 2,也就是数字在下标为 2 和下标为 4 的两个位置都出现了,因此找到一个重复的数字。
代码实现如下:
package TestProblem;
public class Test51 {
/**
* 题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,
* 但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
* 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
*
* @param number
* @return
*/
public static int duplicate(int[] number){
if(number==null || number.length<1){
return -1;
}
//判断输入是否是在[0,number.length-1]之间
for (int i = 0; i < number.length; i++) {
if(i<0||i>number.length){
return -1;
}
}
for (int i = 0; i < number.length; i++) {
//判断number[i]与i是否相等
while (number[i]!=i) {
//如果相等,则有重复元素i位置与number[i]位置相等
if(number[number[i]]==i){
return number[i];
}
//如果不相等则交换
else{
swap(number,i,number[i]);
}
}
}
return -1;
}
private static void swap(int data[],int x, int y) {
// TODO Auto-generated method stub
int temp=data[x];
data[x]=data[y];
data[y]=temp;
}
public static void main(String[] args) {
int num[]={2,3,1,0,2,5,3};
System.out.println("重复的数字:"+duplicate(num));
}
}