您的位置:首页 > Web前端

剑指Offer:数组中重复的数字

2018-03-23 15:12 330 查看
在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。例如:如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

首先想到的方法是将数组进行排序,我们遍历一遍数组就可以找出重复的数字了。排序一个数组的时间复杂度为O(nlogn)。

我们还可以使用哈希表来解决这一问题。我们从头到尾遍历数组,如果哈希表中不存在当前遍历的数字,那么就在哈希表中存放这个数字;如果当前遍历的数字存在哈希表中了说明这个数字就是重复的。这个方法的时间复杂度为O(n),但是空间复杂度为O(n)。我们思考有没有空间复杂度为O(1)的方法。

根据题目我们知道数组大小为n,所有数字的范围为0至n-1,显然,如果不存在重复的数字当数组排序后下标i对应的数字就是i;如果存在重复的数字有些位置存在多个数字,而有的位置没有数字。

算法思路如下:

从头遍历数组中的每个数字,每次扫描到的数字记为m。当扫描到下标为i的数字是,首先比较m是否等于i:

如果相等,直接扫描下一个数字;

如果不相等,再拿m和第m个数字相比较:

如果它和第m个数字相等那么我们就找到了一个重复数字。

如果它和第m个数字不相等,就把第i个数字和第m个数字交换,把m放到属于它的位置上。再重复这个比较、交换过程,直至找到重复的数字。

实现代码:

public static boolean DuplicatedNum(int numbers[],int length,int[] duplication) {
if(numbers==null||length==0||duplication==null){
return false;
}
for(int i=0;i<length;i++){
if(numbers[i]<0||numbers[i]>length-1){
return false;
}
}
for(int i=0;i<numbers.length;i++){
int m=numbers[i];
if(i==m){
continue;
}else{
if(m==numbers[m]){
duplication[0]=m;
return true;
}else{
int temp = numbers[i];
numbers[i] = numbers[m];
numbers[m] = temp;
}
}
}
return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息