您的位置:首页 > 其它

数组中重复的数字

2016-06-25 17:27 253 查看

题目

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

解题

HashMap或者数组占用空间

利用数组,A[i]表示i值出现的次数

public boolean duplicate(int numbers[],int length,int [] duplication) {
if(numbers == null || numbers.length <=0)
return false;

boolean[] A = new boolean[length];
for(int num:numbers){
if(A[num]){
duplication[0] = num;
return true;
}else{
A[num] = true;
}
}
return false;
}


讨论中推荐解法

利用现有数组设置标志,当一个数字被访问过后,可以设置对应位上的数 + n,之后再遇到相同的数时,会发现对应位上的数已经大于等于n了,那么直接返回这个数即可。

public boolean duplicate(int numbers[],int length,int [] duplication) {
if(numbers == null || numbers.length <=0)
return false;

for ( int i= 0 ; i<length; i++) {
int index = numbers[i];
if (index >= length) {
index -= length;
}
if (numbers[index] >= length) {
duplication[0] = index;
return true;
}
numbers[index] = numbers[index] + length;
}

return false;
}


上面解题的关键就是:数组的id和数组值是对于的,根据数组值可以找到值得值。

题目说明是0-n-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;
//                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
//    这里要特别注意~返回任意重复的一个,赋值duplication[0]
// Return value:       true if the input is valid, and there are some duplications in the array number
//                     otherwise false
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(numbers == null || numbers.length <=0)
return false;

int low = 0;
int high = numbers.length -1;
quickSort(numbers,0,high);
for(int i=0;i<high;i++){
if(numbers[i]==numbers[i+1]){
duplication[0]=numbers[i];
return true;
}
}
return false;
}
public void quickSort(int[] A,int low,int high){
if(low >high)
return;
int mid = partition(A,low,high);
quickSort(A,low,mid-1);
quickSort(A,mid+1,high);
}
public int partition(int[] A,int low,int high){
int x = A[high];
int i = low -1;
int j = low;
while(j<high){
if(A[j] <= x){
i++;
swap(A,i,j);
}
j++;
}
i++;
swap(A,i,high);
return i;
}
public void swap(int[] A,int i,int j){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}


本打算利用partition找到中间划分的id,id和numbers[id]比较,发现这样做不行,直接写出快排再找了

《剑指offer》上解法

1、判断输入数组有无元素非法

2、从头扫到尾,只要当前元素值与下标不同,就做一次判断,numbers[i]与numbers[numbers[i]],相等就认为找到了

重复元素,返回true,否则就交换两者,继续循环。直到最后还没找到认为没找到重复元素,返回false

public class Solution {
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(numbers == null || numbers.length <=0)
return false;

//判断每一个元素是否非法
for(int i=0;i<length;++i){
if(numbers[i]<=0||numbers[i]>length-1)
return false;
}
for(int i=0;i<length;++i){
while(numbers[i]!=i){
if(numbers[i]==numbers[numbers[i]]){
duplication[0] = numbers[i];
return true;
}
//交换numbers[i]和numbers[numbers[i]]

swap(numbers,i,numbers[i]);
}
}
return false;
}

public void swap(int[] A,int i,int j){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: