题目:找出数组中重复的数字
在一个长度为n的数组里所有的数字都在0~n-1的范围内。数组中某些数组是重复的,但不知道有几个数组重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。要求时间复杂度为O(n),空间复杂度为O(1); 例如:如果输入长度为7的数组[2,3,1,3,3,6],那么对应的输出的重复数字为3;
解题思路
思路一:
通过将数组排序变成一段有序数组,取数组的第0个元素与第1个元素比较,如果相等找到重复数字;不相等拿第1个元素与第2个比较,相等则找到重复数字,否则依次比较下去。 但是排序一个长度为n的数组需要O(nlogn)的时间复杂度;
思路二:
利用hash表来解决;从头到尾按照顺序扫描数组的每个数组,每扫描一个数字的时候,判断哈希表里是不是已经包含这个数字。如果哈希表没有这个数字,则把它加入到哈希表中。存在的话表示已经找到一个重复素组。算法的时间复杂度O(n),但是创建了一个O(n)的哈希表,空间复杂度不相符;
思路三:
数组长度为n,数组中的数字都在0~n-1的范围内,如果这个数组中没有重复数字,那么当数组排序之后数字i将出现在下标为i的位置。由于数组中有重复数字,有些位置可能存在多个数字,同时有些位置可能没有数字。时间复杂度为O(n),空间复杂度为O(1);
解题代码
private static Boolean duplication(int[] number, int length) {
if (number == null && number.length <= 0) {
return false;
}
for (int i = 0; i < length; i++) {
while (number[i] != i) {
if (number[i] == number[number[i]]) {
System.out.printf("重复数字 ".concat(String.valueOf(number[i])));
return true;
}
swap(number, i, number[i]);
}
}
return false;
}
private static void swap(int[] number, int i, int j) {
int n = number[i];
number[i] = number[j];
number[j] = n;
}
接下来改变下题目,不修改数组找出重复的数字又该如何做?
不修改数组找出重复的数字
在一个长度为n的数组中所有数字都在0~n-1的范围内,所有数组中至少有一个数字是重复的。找出数组中任意一个重复的数字,但不能修改输入的数组。
解题思路
思路一:
创建一个长度为n的辅助数组,逐一把原数组的每一个数按照数值复制到辅助数组相对应的下标中,这样很容易知道那个数字有没有重复。但是空间复杂度为O(n)
思路二:
首先想想为什么会出现重复数字?假如没有重复数字,那么从1~n的范围内只有n个数字。由于数组里包含超过n个数字,所以一定包含重复的数字。例如:{2,2,4,1,3,5,6,5},长度为8的数组,所有的数字都在1-7中间,将1-7分为2段,一段为1-4,另一段为5-7,统计1-4中间数字出现的次数为5
解题代码
private static int getDuplication(int[] number, int length) {
if (number == null && number.length <= 0) {
return -1;
}
int start = 1;
int end = length - 1;
while (end >= start) {
int mid = ((end - start) >> 1) + start;
int count = countRange(number, length, start, end);
if (end == start) {
if (count > 1) {
return start;
} else {
break;
}
}
if (count > (mid - start + 1)) {
end = mid;
} else {
start = mid + 1;
}
}
return -1;
}
private static int countRange(int[] number, int length, int start, int end) {
if (number == null) return 0;
int count = 0;
for (int i = 0; i > length; i++) {
if (number[i] >= start && number[i] <= end) count++;
}
return count;
}
后记
摘自《剑指Offter》