题目:找出数组中重复的数字
描述:在一个长度为n的数组里所有的数字都在0~n-1的范围内,数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应输出的重复数字是2或者3。
解决办法:
1 将数组排序,然后从头到尾进行扫描,维护一个变量指向当前下标的下一个元素,然后比对当前元素与下一个元素是否相等,若相等则直接返回即可,这种做法排序时间复杂的较高。
2 我们注意到数组的长度为n,而元素的范围在0~0-1之间,当数组中没有重复数据的理想状态下,把数组从小到大排好序,这时数组下标的值会与数组内元素的值是一样的如大小为4的数组中没有重复数据的状态下,从小到大排好序后为{0,1,2,3},这样下标为0的数组元素值就是0,下标为1的数组元素值就是1.....题目给我们的数组是乱序且有重复的,当我们扫描到下标为i的数字时,首先比较数字(这里假设这个数字是y)是不是i,如果是,接着扫描下一个,如果不是,则再拿它和第y个数字比较,如果它和第y个数字相等,那么就找到一个相等的数字啦,如果不相等,就将第i个元素和第y个元素进行交换,把y放到属于它自己的位置,接下来再重复比较、交换,直到我们发现一个重复的数字。
数字中重复的数字
// 解法2 解法1不推荐
public static int getDuplication(int[] arr) {
if (arr.length<1) {
return -1;
}
int i = 0;
while (i<arr.length) {
if(arr[i] != i) {
// 相等就直接返回
if (arr[arr[i]] == arr[i]) {
return arr[i];
} else {
// 不相等 进行交换 交换完继续计较交换来的这个数 所以这里没有i++
int temp = arr[i];
arr[i] = arr[temp];
arr[temp] = temp;
}
} else {
i++;
}
}
// 跑完发现没有相等的数
return -1;
}
总结:寻找规律,发现特殊的情况,这样就能快速找出重复元素了。