题目:在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
以数组{2,3,1,0,2,5,3}为例来分析找到重复数字的步骤。数组的第0个数字(从0开始计数,和数组的下标保持一致)是2,与它的下标不相等,于是把它和下标为2的数字1交换。交换之后的数组是{1.3.2.0.2.5.3}。此时第0个数字是1,仍然与它的下标不相等,继续把它和下标为1的数字3交换,得到数组{3,1,2,0,2,5,3}.接下来继续交换第0个数字3和第3个数字0,得到数组{0,1,2,3,2,5,3}。此时第0个数字的数值为0,接着扫描下一个数字。在接下来的几个数字中,下标为1,2,3的三个数字分别为1,2,3,它们的下标和数值都分别相等,因此不需要做任何操作。接下来扫描到下标为4的数字2.由于它的数值与它的下标不相等,再比较它和下标为2的数字。注意到此时数组中下标为2的数字也是2,也就是数字在下标为2和下标为4的两个位置都出现了,因此找到一个重复的数字。
bool findDoubleNum(int a[], int len, int *ret) {
if (a == NULL || len < 2 || NULL == ret) {
return false;
}
int i = 0;
while (i < len) {
int num = a[i];
while (i != num) {
// 尝试跟a[num]位置的换
// 如果凑巧a[i] 和 a[num] 一样,那么直接返回
if (a[num] == a[i]) {
*ret = a[i];
return true;
}
int temp = a[num];
a[num] = a[i];
a[i] = temp;
num = a[i];
}
i++;
}
return false;
}
int doubleNum[] = {4,3,1,0,2,5,3};
int doubleNumRet;
findDoubleNum(doubleNum,7,&doubleNumRet);