1.题意
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
示例:例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
2.思路
思路1:“哈希表”实现
从头到尾顺序扫描数组的每个数字,每扫描到一个数字的时候,都可以用的时间来判断哈希表里是否已经包含了这个数字。如果还没有这个数字,就把它加入到哈希表。如果哈希表中已经存在该数字,就找到了一个重复的数字。
时间复杂度:
空间复杂度:
思路2:
创建一个长度为n的数组,然后逐一把原数组的每个数字复制到辅助数组中。
如果原数组中的数字是m,就将该数组保存在辅助数组下标为m的位置。
时间复杂度:
空间复杂度:
思路3:
numbers数组元素的范围(0到n-1)与 numbers数组下标index的范围一致。
可以考虑从numbers[i] 与 index 的关系出发解决问题。
例如:
当扫描到numbers[i] 时, index = numbers[i] (如果index < 0, index += length, 保证index >= 0)
我们让numbers[index]变为负数(通过减length变为负数,注意这里不可以取相反数,因为0的相反数为0,不能判断重复)。
这样,通过numbers[index]是否为负就可以找出这个重复出现的数字。
如示例数据:
index 0 1 2 3 4 5 6
numbers {2,3,1,0,2,5,3}
numbers[0] = 2 index = 2 numbers[index] = -6;
numbers[1] = 3 index = 3 numbers[index] = -7;
numbers[2] = -6 index = -6 + 7 numbers[index] = -4;
numbers[3] = 0 index = 0 numbers[index] = -5;
numbers[4] = 2 index = 2
numbers[index = 2] 为负数 此数字已经出现过,重复,返回numbers[4]
时间复杂度:
空间复杂度:
3.实现
思路1的实现
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) {
unordered_map<int, int> hash;
for(int i = 0; i < length; i++)
{
if(hash.find(numbers[i]) == hash.end())
hash[numbers[i]] = i;
else
{
*duplication = numbers[i];
return true;
};
}
return false;
}
};
思路2的实现
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) {
vector<int> helper(length, -1); //辅助数组
for(int i = 0; i < length; i++)
{
if(helper[numbers[i]] == -1)
{
helper[numbers[i]] = numbers[i]; //数组numbers[i]放在辅助数组下标为numbers[i]的位置
}
else
{
*duplication = numbers[i]; //发现重复数字
return true;
}
}
return false;
}
};
思路3的实现
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 <= 0||numbers == NULL)
return false; //鲁棒性
for(int i = 0; i < length; i++)
{
int index = numbers[i];
if(index < 0)
index += length; //保证index >= 0
if(numbers[index] < 0)
{
*duplication = index; //发现重复项
return true;
}
else
numbers[index] -= length;
}
return false;
}
};
4.相关问题