您的位置:首页 > 其它

不修改数组找出重复的数字

2018-03-30 14:56 441 查看

不修改数组找出重复的数字

剑指offer

在一个长度为n+1的数组里面的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为9的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。

方法一

创建一个新n+1的数组data,遍历原来的数组如 2 将2存到 data[2]中, 3存到data[3]中…. 等下下次一遍历到3 发现data[3]=3 说明重复了。

`

public static void main(String[] args) {
int [] array={2,3,5,4,3,2,6,7};
//创建一个新的数组
int [] newArray=new int[array.length];
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<newArray.length;i++){
//赋值为-1
newArray[i]=-1;
}

for(int i=0;i<array.length;i++){
if(newArray[array[i]]==array[i]){
map.put(array[i],map.get(array[i])+1);
}else{
newArray[array[i]]=array[i];
map.put(array[i],1);
}
}

map.forEach((key,value)->{
if (value>1){
System.out.println(key +" : "+value);
}
});


`

结果:



分析:

统计个数是我自己加上去的

算法时间复杂度为 O(n),空间复杂度O(n)

方法二

使用二分法。 如:{2,3,5,4,3,2,6,7} 先二分,先统计在1~4里面的数字个数如果大于4则说明1~4里面有重复数字,否则5~7里面有重复数字。重复上面操作。

`

public static void main(String[] args) {
int [] array={2,3,5,4,3,2,6,7};
int length=array.length-1;
int start=1,end=length;

while(start<=end){
//取中
int middle=((end-start)>>1)+start;
int count= getCount(array,start,middle);
if(start==end){
if(count>1){
//输出重复数字
System.out.println(start);
break;
}else {
break;
}
}
if(count>(middle-start+1)){
end=middle;
}else{
start=middle+1;
}
}

}
//查找数组中值位于start和end之间的元素个数
public static int getCount(int[] array,int start,int end){
if (array==null)
return 0;
int count=0;
for(int i=0;i<array.length;i++){
if(array[i]>=start&&array[i]<=end){
count++;
}
}
return count;
}


`

结果:



分析:二分查找logn ,但是getCount每个数组遍历一变 n,时间复杂度为O(nlogn),空间复杂度为O(1)。但是这个方法有个问题不能找出所有的重复元素

如{2,2,4,4,5,5} 找到的元素会是4。

start=1,end=5,middle=3。 1~3中元素有2个则4~5有重复

start=4,end=5,middle=4。 4有2个元素

start=4,end=4,middle=4, 返回4。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐