【剑指offer】50:数组中重复的数字
题目描述:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
解题思路:
由于题目中告诉我们所有的数字都在0到n-1的范围内,因此如果没有重复,那么所存储的值也正好是0到n-1这n个数字,我们把原数组重新排列为一个元素和对应下标值相同的数组。
具体思路如下:从头到尾扫描整个数组中的数字,当扫描到下标为i的数字时,首先比较这个数字是不是等于下标i(数组存放原则:numbers[i] == i)。如果是,接着比较下一个数字;如果不是,则将其与第i个数字比较,若与第i个数字相同,则说明它就是一个重复数字,如果不同,就将其与第i个数字进行交换,也就是把它放到自己应在的位置去。重复这个过程,直到该位置上的数与下标相同为止。
例如: 例如[2,3,1,0,2] 遍历0位元素2:(交换0位元素2和2位元素1)->[1,3,2,0,2] 遍历0位元素1:(交换0位元素1和1位元素3)->[3,1,2,0,2] 遍历0位元素3:(交换0位元素3和3位元素0)->[0,1,2,3,2] 依次遍历0、1、2、3位置元素,都符合存放原则numbers[i] = i,不做任何操作 遍历末位元素2,此时末位元素2和2位元素2相等,出现了两次,即数字2位重复元素代码实现:
(C语言)
int duplicate(int* numbers, int numbersLen ) { // write code here if (numbersLen <= 1) { return -1; } for (int i = 0; i < numbersLen; i++) { if (numbers[i] != i) { if (numbers[i] == numbers[numbers[i]]) { return numbers[i]; }else { int temp = numbers[numbers[i]]; numbers[numbers[i]] = numbers[i]; numbers[i] = temp; } i--; //遍历完0位元素以及交换完数字后,如果0位元素仍不符合数组存放原则:numbers[i] = i,那么还要重新遍历0位元素 } } return -1;

浙公网安备 33010602011771号