一、题意:长度为n+1的数组里的所有数字都在1~n的范围内,找出任意一个重复复的数字,但不能修改原数组。
二、思路:
1、创建一个长度为n+1的辅助数组,在O(n)的复杂度里面可以解决这个问题,空间复杂度也为O(n);
2、时间换空间,采用类似于二分查找的方式,用中间数字对数组中的数字进行划分,然后在最后某个长度为1的空间中总能找到一个重复数字。这种方法时间复杂度为O(nlogn),但空间复杂度为O(1);
三、代码:
1 #include"iostream" 2 #include"stdio.h" 3 using namespace std; 4 const int MAXN=1000; 5 6 int CountRange(const int * numbers,int length,int start ,int end) 7 { 8 if(numbers==nullptr) 9 return 0; 10 int count=0; 11 for(int i=0;i<length;i++) 12 if(numbers[i]>=start&&numbers[i]<=end) 13 ++count; 14 return count; 15 } 16 17 int GetDuplication(const int * numbers,int length) 18 { 19 if(numbers==nullptr || length<=0) 20 return -1; 21 22 int start=1; 23 int end=length-1; 24 while(end>=start) 25 { 26 int middle=((end-start)>>1)+start;//求平均值的良好 习惯 27 int count=CountRange(numbers,length,start,middle); 28 if(end==start) 29 { 30 if(count>1) return start; 31 else break; 32 } 33 if(count>(middle-start)+1) 34 end=middle; 35 else 36 start=middle+1; 37 } 38 return -1; 39 } 40 41 int main() 42 { 43 int length; 44 while(cin>>length) 45 { 46 int numbers[MAXN]; 47 for(int i=0;i<length;i++) 48 cin>>numbers[i]; 49 int res=GetDuplication(numbers,length); 50 if(res!=-1) 51 cout<<"the duplicate number is: "<<res<<endl; 52 else 53 cout<<"wrong input!"<<endl; 54 } 55 return 0; 56 }