题目:
在一个长度为n的数组里的所有数字范围在0~n-1,找出数组中任意一个重复出现的数字
解法一:利用map容器统计每个数字出现的次数
解法二:把数字放到本来的位置,若是冲突就是重复了。
例如: 2 3 1 0 2 5 3
数组的0号位置不是0 ,值是2,所以将其与下标为2的数字交换得到 1 3 2 0 2 5 3 ,这样的目的是把数字放到正确的位置。
此时的0号位置是1, 不是0, 所以和1号位置数字交换,
得到 3 1 2 0 2 5 3
此时0号位置是3,和3号位置数字交换得到
0 1 2 3 2 5 3 ,此时0号位置是0,所以可以扫描数组下一个位置,即1号位置,发现1号位置就是1,不做操作,扫描2号位置,发现2号位置是2,不操作,扫描下一个位置3号位置,发现是3,不操作,扫描下一个位置4号位置,不是4
发现是2, 这时候我们在与2号位置的数字交换的时候发现2号位置也是2了,所以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) {
if(numbers == nullptr || length <= 0)//判断参数合法性
return false;
for(int i = 0; i < length; i++)//判断数字范围合法性
{
if(numbers[i] >= length || numbers[i] < 0)
return false;
}
for(int i = 0; i < length; i++)
{
while(i != numbers[i])
{
if(numbers[i] == numbers[numbers[i]])//重复出现
{
*duplication = numbers[i];
return true;
}
//交换numbers[i]和numbers[numbers[i]] 位运算加快
int temp = numbers[i];
numbers[i] = numbers[i] ^ numbers[temp];
numbers[temp] = numbers[i] ^ numbers[temp];
numbers[i] = numbers[i] ^ numbers[temp];
}
}
return false;
}
};
时间复杂度是O(n),空间复杂度是O(1)