题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路和实现
way1(参考剑指offer)
数组中的数字都是在0~n-1的范围内,如果数组中没有重复的数字,当数组排序后数字 i 出现在下标为 i 的位置。 因为数组中有重复的数字,所有有些位置可能存在多个数字,有些位置可能没有数字。
思路: 重新排列数组,从头到尾扫描,
扫描到下标为i的数字m,比较数字m是不是等于 下标i:
如果是,扫描下一个数字
如果不是,将下标为i的数字m 和下标为m的数字比较:
如果相等,则找到了一个重复的数字(下标为i和下标m的位置都出现数字m)
如果不相等,则将下标为i的数字m 和下标为m的数字交换,将m放到属于它的位置。
重复此过程,直到发现重复的数字。
举例:
实现:
public class Solution {
public boolean duplicate(int numbers[], int length, int[] duplication) {
if (numbers == null || length == 0)
return false;
for (int i = 0; i < length; i++) {
if (numbers[i] < 0 || numbers[i] > length - 1)
return false;
}
for (int i = 0; i < length; i++) {
while (numbers[i] != i) {
if (numbers[i] == numbers[numbers[i]]) {
duplication[0] = numbers[i];
return true;
}
//交换numbers[i]和numbers[numbers[i]]
int temp = numbers[i];
numbers[i] = numbers[temp];
numbers[temp] = temp;
}
}
return false;
}
}
way2
思路: 不需要额外的数组或者hash table来保存,题目里写了数组里数字的范围保证在0 ~ n-1 之间,所以可以利用现有数组设置标志,当一个数字m被访问过后,可以设置索引位置为m对应的值 + n,之后再遇到相同的数时,会发现对应索引位置上的数已经大于等于n了,那么直接返回这个数即可。
实现:
public class Solution {
public boolean duplicate(int numbers[],int length,int [] duplication) {
duplication[0]=-1;
if(numbers==null || length==0 )
return false;
for (int i = 0; i <length ; i++) {
int index=numbers[i];
if(index>=length)
index-=length;
if(numbers[index]>=length){
duplication[0]=index;
return true;
}
numbers[index]+=length;
}
return false;
}
}
例如:
-
n=7 {2,3,1,0,2,5,3}
int i = 0; i <length ;
int index=numbers[0]=2;
if(index>=length)
index-=length;
if(numbers[index]>=length){
duplication[0]=index;
return true;
}
numbers[2]+=length numbers[2]=1+7=8;
i++ ; i=1 -
n=7 {2,3,8,0,2,5,3}
int i = 1; i <length ;
int index=numbers[1]=3;
if(index>=length)
index-=length;
if(numbers[index]>=length){
duplication[0]=index;
return true;
}
numbers[3]+=length ; numbers[3]=0+7=7
i++ ; i=2 -
n=7 {2,3,8,7,2,5,3}
int i = 2; i <length ;
int index=numbers[2]=8;
if(index>=length)
index-=length; index=1
if(numbers[index]>=length){
duplication[0]=index;
return true;
}
numbers[1]+=length ; numbers[1]=3+7=10
i++ ; i=3 -
n=7 {2,10,8,7,2,5,3}
int i = 3; i <length ;
int index=numbers[3]=7;
if(index>=length)
index-=length; index=7-7=0
if(numbers[index]>=length){
duplication[0]=index;
return true;
}
numbers[0]+=length ; numbers[0]=2+7=9
i++ ; i=4 -
n=7 {9,10,8,7,2,5,3}
int i =4; i <length ;
int index=numbers[4]=2;
if(index>=length)
index-=length;
if(numbers[index]>=length){
duplication[0]=index =2;
return true;
}
参考
https://www.nowcoder.com/profile/456591/codeBookDetail?submissionId=1512271