题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
我的解题思路:
暴力穷举法,依次对比每个数,有重复就return。
边界条件:
输入的数组为空
复杂度:
时间复杂度:O(n2) 空间复杂度:O(1)
解决中遇到的问题:
循环时,两个循环嵌套,第二个循环代表要和第一个循环中比较的数,由于我第二个循环也和第一个循环的起始值一样,所以一直判断是true,这里注意,这种方式第二个循环的初始值应该是i+1。
完整代码:
public class Solution {
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(length == 0 || duplication == null){
return false;
}
for(int i = 0 ;i < length;i++){
//duplication[0] = numbers[i];不用复制,直接比较数组位置就好
for(int j= i+1;j < length;j++){
if(numbers[j] == numbers[i]){
duplication[0] = numbers[j];
return true;
}
}
}
//duplication[0] = -1;
return false;
}
}
优化思路:
1.排序后再比较
数组中比较大小这种题应该考虑下是否能排序。先排序,如果有重复的,那么必存在相邻两个数相等的情况。这样就少了嵌套的循环。
时间复杂度: 空间复杂度O(1)
注意要import对应的包,不然报错,找不到的。
import java.util.Arrays;
public class Solution {
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(length == 0 || duplication == null){
return false;
}
Arrays.sort(numbers);
for(int i = 0 ;i < length-1;i++){
//duplication[0] = numbers[i];不用复制,直接比较数组位置就好
if(numbers[i] == numbers[i+1]){
duplication[0] = numbers[i];
return true;
}
}
//duplication[0] = -1;
return false;
}
}
2.利用hash表
从头开始遍历,从hash表中找当前元素,如果存在则重复,不存在则把这个数加入hash表。
时间复杂度O(n),用了Hash表,空间复杂度是O(n).
3.利用特性
题目中的这句话很关键:
因此,我们可以将数组元素的值和数组的下标联系起来。逐个判断,判断第i个数Q,看其取值时候为i,不是的话查找位置为Q的元素,看其值是否等于Q,不等于则交换二者的位置。再继续判断现在i位置上的数W是否等于位置w上的数,不等于则交换,等于则移到下一位继续判断。
完整代码:
public class Solution {
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(length == 0 || duplication == null){
return false;
}
for(int i=0;i<length;i++){
while(i != numbers[i]){
int j = numbers[i];
if(numbers[i] == numbers[j]){
duplication[0] = numbers[i];
return true;
}
int temp = numbers[j];
numbers[j] = numbers[i];
numbers[i] = temp;
}
}
return false;
}
}
时间复杂度O(n),假设12300。最坏可以通过n次循环找到重复元素。因为前面的n-1次循环可以将n-1个数放在他们对应的位置上,相当于从小到大排序,后面的数比和前面对应位置的数相等。