题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
public class Solution {
// Parameters:
// numbers: 输入的数组
// length: 数组的长度
// duplication: 返回任意重复的一个,赋值duplication[0]
// Return value: true if the input is valid,
// and there are some duplications in the array number
// otherwise false
public boolean duplicate(int numbers[],int length,int [] duplication) {
/**
* 因为数组里的数字都在 0到n-1 的范围
* 所以k数组就是记录哪个数字已经出现了
* 出现过的数字m,k[m]为true
* 如果再次出现数字m,k[m]已经为true时,就是第一个重复的数字了
*/
boolean[] k = new boolean[length];
for (int i = 0; i < length; i++) {
if (k[numbers[i]] == true) {
duplication[0] = numbers[i];
return true;
}
k[numbers[i]] = true;
}
return false;
}
}
剑指offer书上还有其他方法:
public static boolean duplicate(int numbers[],int length,int [] duplication) {
/**
* 重排数组:
* 从头到尾扫描数组
* 当扫描的下标为i的数字时,首先比较这个数字m是否等于i
* 如果是,则扫描下一个数字
* 如果不是,就拿它与下标为m的数字比较
* 如果它与第m个数相等,就找到一个重复数字
* 如果它和第m个数字不相等,则交换第i个数字和第m和数字,把m放到属于它的位置
*/
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;
}
int tmp = numbers[i];
numbers[i]=numbers[tmp];
numbers[tmp]=tmp;
}
}
return false;
}
numbers[i]:
2 3 1 0 2 5 3
1 3 2 0 2 5 3
3 1 2 0 2 5 3
0 1 2 3 2 5 3