剑指offer:面试题3—数组中重复的数字
2019-05-31 17:08
459 查看
题目描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或3。
解决(代码在牛客网上通过):
1.将数组排序,从头至尾扫描排序后的数组,即可。
[code]import java.util.Arrays; public boolean duplicate(int numbers[],int length,int [] duplication) { boolean result=false; if(numbers==null) return false; Arrays.sort(numbers); for(int i=0;i<numbers.length-1;i++){ if(numbers[i]==numbers[i+1]){ duplication[0]=numbers[i]; result=true; break; } } return result; }
排序所需时间复杂度为O(nlogn)
2.使用大小为n的哈希表来解决
[code] public boolean duplicate(int numbers[],int length,int [] duplication) { int[] a=new int[length]; boolean result=false; for(int i=0;i<length;i++){ if(a[numbers[i]]==0){ a[numbers[i]]++; }else if(a[numbers[i]]==1){ duplication[0]=numbers[i]; result=true; break; } } return result; }
时间复杂度O(n),空间复杂度O(n)
3.空间复杂度O(1)的方法
从头至尾扫描数组中的每个数字,当扫描到下标为i的数字m时,首先比较这个数字m是不是等于i,如果是,则继续扫描;如果不是,则与下标为m的数字比较,如果相等则找到重复数字;如果不等,则交换位置。
[code]public boolean duplicate(int numbers[],int length,int [] duplication) { boolean result=false; if(numbers==null) return false; for(int i=0;i<length;i++){ if(numbers[i]!=i){ int flag=numbers[numbers[i]]; if(flag==numbers[i]){ result=true; duplication[0]=flag; break; } numbers[numbers[i]]=numbers[i]; numbers[i]=flag; } } return result; }
时间复杂度为O(n),空间复杂度O(1)
4.不修改数组找出重复的数字
题目:长度为n+1的数组里的所有数字都在1~n范围内,所以至少有一个数字是重复的,请找出任意一个重复的数字,但不能修改输入的数组。
1)创建一个新的数组,一次复制到对应下标位,即可判断重复。
空间复杂度O(n)
2)666方法
举例:数组{2,3,5,4,3,2,6,7},1~7,8个数字,
中间数字4将1~7分成两段,1~4,5~7;1~4出现了5次,5~7出现了3次;则重复数字出现在1~4;
1~4一分为二,1~2出现了两次,3~4出现了三次,则重复数字出现在3~4;
[code]public static boolean duplicate(int numbers[],int length,int[] duplication) { int start=1; int end=length-1; boolean result=false; while(end>=start) { int mid=(end-start)/2+start; int count=countRange(numbers,length,start,mid); if(end==start) { if(count>1) { result=true; duplication[0]=start; return result; } else break; } if(count>(mid-start+1)) end=mid; else start=mid+1; } return result; } public static int countRange(int[] numbers, int length,int start,int mid) { if(numbers==null) return 0; int count=0; for(int i=0;i<length;i++) { if(numbers[i]>=start && numbers[i]<=mid) { count++; } } return count; }
使用二分法,时间复杂度O(nlogn);空间复杂度O(1)
但这种方法不能保证找出所有重复的数字,如举例中的2,就无法判断。
相关文章推荐
- 剑指Offer面试题51(Java版):数组中重复的数字
- 剑指offer-面试题51-数组中重复的数字
- 剑指offer——面试题51:数组中重复的数字
- 《剑指offer-面试题3-数组中重复的数字》
- 剑指offer 面试题3 数组中重复的数字
- 《剑指offer》面试题03:数组中重复的数字
- 《剑指Offer》学习笔记--面试题51:数组中重复的数字
- 剑指Offer 面试题3:数组中的重复数字
- 剑指Offer 面试题3.数组中重复的数字
- 剑指offer面试题(三)数组中重复的数字
- 剑指offer - 面试题51:数组中重复的数字
- 剑指offer面试题[51]-数组中重复的数字
- (剑指Offer)面试题51:数组中重复的数字
- 《剑指offer》面试题3:数组中重复的数字
- 剑指Offer(第二版)面试题56:数组中数字出现的次数
- 剑指offer系列之四十九:数组中重复的数字
- 面试题3:数组中重复的数字
- 《剑指offer》-请找出数组中任意一个重复的数字
- 剑指Offer面试题40(Java版):数组出现一次的数字
- (PHP实现剑指offer)数组中重复的数字