题目一 :找出数组中重复的数字
在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但是不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数组2或者3。
第二种解法: 重新排列数组的方法 ---- 时间复杂度O(n), 空间复杂度O(1)
分析理解:
* 幼儿园的10个小朋友随机的坐在小板凳上,每个人手中都握有一个数字(0-9的任意数)
* 现在老师要根据小朋友手中的数字排序;过程如下----
* 1. 找到第一个小板凳上的小朋友A,如果小朋友A握的号码 == 0,说明她坐对了位置,不用
* 换位置;老师会去看第二个小板凳上的小朋友;
* 2. 如果手中的号码是 3,说明她不应该坐在第一个小板凳;然后老师带着她去找
* 坐在 3号的小板凳上的小朋友B,
* 3. 如果3 号小板凳上的小朋友B 拿的号码是 3号,说明A, B 两个小朋友的号码重复了;
* 4. 如果B拿的号码是4号, 那么老师会让 A 坐在 3号板凳上,让 B 暂时做到 第一个小板凳
* 上,然后老师再重复 1---4步
代码实现:
/**
* 重新排列数组的方法 ---- 时间复杂度O(n), 空间复杂度O(1)
* 理解: 对号入座,如果数组中没有重复的数字,经过排序后每个数字 == 它所处的位置
* 例如 array[3] = 3; array[4] = 4
* 个人分析: 幼儿园的10个小朋友随机的坐在小板凳上,每个人手中都握有一个数字(0-9的任意数)
* 现在老师要根据小朋友手中的数字排序;过程如下----
* 1. 找到第一个小板凳上的小朋友A,如果小朋友A握的号码 == 0,说明她坐对了位置,不用
* 换位置;老师会去看第二个小板凳上的小朋友;
* 2. 如果手中的号码是 3,说明她不应该坐在第一个小板凳;然后老师带着她去找
* 坐在 3号的小板凳上的小朋友B,
* 3. 如果3 号小板凳上的小朋友B 拿的号码是 3号,说明A, B 两个小朋友的号码重复了;
* 4. 如果B拿的号码是4号, 那么老师会让 A 坐在 3号板凳上,让 B 暂时做到 第一个小板凳
* 上,然后老师再重复 1---4步
* 大致的理解过程就是这样了!
* @param array
* @return
*/
private static int getDuplitNumber2(int[] array) {
// 如果当前数组为空,则返回 -1
if (array == null || array.length == 0) {
return -1;
}
// 以 {2, 3, 2, 0, 4, 5, 3} 为例
for (int i = 0; i < array.length; i++) {
// 判断当前位置是否坐对了人
while (array[i] != i) {
// 如果有人抢占了位置,就去比较号码牌
if (array[i] == array[array[i]]) {
// 出现了重复
return array[i];
}
// 如果不等就交换顺序,然后继续比较
int temp = array[i];
array[i] = array[temp];
array[temp] = temp;
}
}
return -1;
}