一题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
二:解题思路
第一种:排序
第二种:借助辅助空间,哈希的思想
借助辅助空间,hash,如果不需要保证原始numbers数字出现的先后顺序,则借助O(n)辅助空间
如果要保证原始顺序,则需要借助O(2n)辅助空间
输入的数组有效且有重复的数字,则返回true
否则,返回false
输出重复的数字,是否要保持他在数组中出现的先后顺序,这个要注意
利用一个[长度][2]二维数组,下标表示0--n-1的n个数,第一列表示第一次出现的位置,第二列表示该数字是否重复
遍历number数组,如果hash[number[i]][1]==0,则number[i]是重复的数,同时保证i与第一次出现的位置相同,防止后面出现重复数字,保存重复
第三种:交换的思想
0~n-1正常的排序应该是A[i]=i;因此可以通过交换的方式,将它们都各自放回属于自己的位置;
当扫描下标为i的数字时,首先比较这个数字的(m)是不是等于i,
如果是,接着扫描下一个数字
如果不是,将他与第m个数字比较,如果相等,就找到第一个重复的数字(第i个位置的数字与m位置的数字重复)
如果与第m个位置的数字不相等,就将i--m位置的数字互换,把m放到属于它的位置上,接下来重复比较,交换的过程
三:代码实现
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
if(length<=1) //如果只包含0,不合法,包含一个数字,不会重复
return false;
int hash[length][2]; //下标代表0--length
memset(hash,-1,sizeof(hash)); //第一列存放数字第一次出现的位置 第二列存放是否重复
//hash初始化-2; 第一个参数是指针或者数组,
//第二个参数是要对该数组初始化的值,第三个参数是整个数组的大小,(注意不是数组的长度)
//strlen返回的字符串的长度 数组的长度 sizeof(a)/sizeof(a[0])
int i;
for(i=0;i<length;i++)
{
if(hash[numbers[i]][0]==-1)
hash[numbers[i]][0]=i; //第一次出现的地址
else if(hash[numbers[i]][0]>=0) //之前写成if 是不对的,上面刚刚出现一次,将-1-->0,下面就判断她重复出现了
hash[numbers[i]][1]=0; //第二次出现,0代表该数重复出现
}
int numOfDuplication=0;
for(i=0;i<length;i++)
{
if(hash[numbers[i]][1]==0 && i==hash[numbers[i]][0]){//重复出现,且只保存第一次出现的,后面重复出现的不保存
*duplication=numbers[i];
numOfDuplication++;
duplication++;
}
}
if(numOfDuplication==0) //无重复
return false;
else
return true;
}
};
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
int i;
if(length<=1)
return false;
for(i=0;i<length;i++)
if(numbers[i]<0 || numbers[i]>length-1)
return false;
int numOfDumplication=0;
for(i=0;i<length;i++){
while(i!=numbers[i]){
if(numbers[i]==numbers[numbers[i]]){
*duplication =numbers[i];
duplication++;
numOfDumplication++;
i++; //遍历下一位
}//发现重复项
else{
int temp=numbers[i];
numbers[i]=numbers[temp];
numbers[temp]=temp;
}
}
}
if(numOfDumplication==0)
return false;
else
return true;
}
};