数组中的重复数字
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思想
1.利用本题的性质,由于所有数字都在0-n-1,因此,如果没有重复则所有数字都顺序排列应该为0-n-1。当数字与数组下标相等时,则进入下次循环,如果不相等则循环知道相等,在循环中判断如果数字和他对应位置值相等则返回真即为有重复值,否则交换位置把数字换到他应有的位置。遍历结束返回false。时间复杂度O(n),空间复杂度O(1)。
(注:在交换时,注意交换的下标。)
public boolean duplicate(int numbers[],int length,int [] duplication) {
if (numbers == null || length < 1)
return false;
int dupLen = 0;
int temp;
for (int i = 0; i < length; i++) {
while (numbers[i] != i) {
if (numbers[i] == numbers[numbers[i]]) {
duplication[dupLen++] = numbers[i];
return true;
}
//这里在写的时候没有注意到numbers[i]与temp相等的问题,导致出现死循环
temp = numbers[i];
numbers[i] = numbers[temp];
numbers[temp] = temp;
}
}
return false;
}
2.先对数组进行排序,然后遍历判断前后是否有重复。时间复杂度O(nlog(n))。
(注:在测试时,不只有返回结果会进行测试,重复数字也在测试范围内。)
public static boolean duplicateSort(int numbers[], int length, int[] duplication) {
if (numbers == null || length == 0) return false;
quickSort(numbers, 0, length-1);
int dupLen = 0;
for (int i = 0; i < length-1; i++) {
if (numbers[i] == numbers[i+1]) {
duplication[dupLen++] = numbers[i];
return true;
}
}
return false;
}
//快速排序
public static void quickSort(int numbers[], int low,int high){
if (low < high){
int p = partition(numbers, low, high);
quickSort(numbers, low, p-1);
quickSort(numbers, p+1, high);
}
}
//快速排序划分算法,返回位置
public static int partition(int numbers[],int low,int high){
int p = numbers[low];
while(low<high){
while(low < high && numbers[high] >= p) high--;
numbers[low] = numbers[high];
//注意,这里low是低位,指针要向上修改,自增
while (low < high && numbers[low] <= p) low++;
numbers[high] = numbers[low];
}
numbers[low] = p;
return low;
}
3.使用HashSet,进行一次遍历,如果数组元素存在,则重复,如果不存在,将其加入到HashSet中。时间复杂度是O(n),缺点是利用了空间为n的hashset。
(注:用HashSet需要导包。)
public static boolean duplicateHash(int numbers[], int length, int[] duplication) {
if (numbers == null || length == 0) return false;
HashSet<Integer> hashSet = new HashSet<Integer>();
int depLen = 0;
for (int i = 0; i < length; i++) {
if (hashSet.contains(numbers[i])) {
duplication[depLen++] = numbers[i];
return true;
} else {
hashSet.add(numbers[i]);
}
}
return false;
}