算法4---数组
1 数组基本概念
2 数组有关的编程练习
1 数组的基本概念
数组就是用下标表示位置的相同类型数据的顺序数据类型,其中机器在给数据分配空间的时候分配的是一块连续的空间。
数组没有什么很多的东西需要补充,值得注意的是,数组作为参数的时候,使用指针的情况;
2 编程练习
1 remove duplicates from sorted array
discription:
given a sorted array,remove the deplicates in place such that each element appear only once and return the new length;
do not allocate extra space for another array,you must do this in place with constant memory.
for example:
given input array A=[1,1,2]
your function should return length=2 ,and A is now [1,2];
1 #include <stdio.h> 2 3 int removeDeduplication(int A[],int n); 4 5 int main() 6 { 7 /*int n; 8 int A[]={}; 9 printf("please input the array with the length of n:\n"); 10 scanf("%d",&n); 11 printf("the length is %d\n",n ); 12 for (int c = 0; c < n; c++) 13 { 14 scanf("%d",&A[c]); 15 } 16 for (int i = 0; i < n; i++) 17 { 18 //printf("the array is: \n"); 19 printf("%d \n",A[i]); 20 } 21 int l=removeDeduplication(A,n); 22 printf("after deduplcate ,the length is:%d\n",l); 23 printf("the array now is: \n"); 24 for (int j = 0; j < l; j++) 25 { 26 27 printf("%d\n",A[j]); 28 } 29 */ 30 int A[10]={1,1,2,2,3,3,3,4,5,6}; 31 int l=removeDeduplication(A,10); 32 printf("the length is %d\n",l); 33 printf("the array now is: \n"); 34 for (int j = 0; j < l; j++) 35 { 36 printf("%d \n", A[j]); 37 } 38 return 0; 39 } 40 41 int removeDeduplication(int A[],int n) 42 { 43 int l=0; 44 if (n==0) 45 { 46 printf("worry array!\n"); 47 } 48 for (int i = 1; i < n; i++) 49 { 50 if (A[l]!=A[i]) 51 { 52 A[++l]=A[i]; 53 } 54 } 55 return l+1; 56 }
2 remove deplicates from sorted array2
descript:
follow up for "remove duplicate":what if duplicates are allowed at most twice?
for example,given sorted array A=[1,1,1,2,2,3];
your function should return length =5,and A is now [1,1,2,2,3]
solve method:
两种解决办法;
1 #include <stdio.h> 2 3 int removeDeplication(int A[],int n); 4 int removeDeplication2(int A[],int n); 5 int main() 6 { 7 int A[10]={1,1,1,2,3,3,3,4,5,6}; 8 int l=removeDeplication(A,10); 9 int l=removeDeplication2(A,10); 10 printf("the length is %d\n",l); 11 printf("the array now is: \n"); 12 for (int j = 0; j < l; j++) 13 { 14 15 printf("%d \n", A[j]); 16 } 17 return 0; 18 } 19 20 int removeDeplication(int A[],int n) 21 { 22 int l=2; 23 if (n<=2) 24 return n; 25 26 for (int i = 2; i < n; i++) 27 { 28 if (A[i]!=A[l-2]) 29 { 30 A[l++]=A[i]; 31 } 32 } 33 return l; 34 } 35 36 37 int removeDeplication2(int A[],int n) 38 { 39 int l=0; 40 for (int i = 0; i < n; ++i) 41 { 42 if (i>0&&i<n-1&&A[i]==A[i-1]&&A[i]==A[i+1]) 43 { 44 continue; 45 } 46 A[l++]=A[i]; 47 } 48 return l; 49 }
3 Search in Rotated Sorted Array
discript:
suppose a array is rotated at some pivot unknown to you beforehand
(i.e, 0,2,3,4,5,6,7 might become 4,5,6,7,0,1,2)
you are given a target value to search .if found in the array return its index,otherwise return -1;
you might assume no dedulicate exists in the array!
methed 1 ,time complex is O(n),space complex is O(1)
1 #include <iostream> 2 3 using namespace std; 4 5 int search(int A[],int n,int target); 6 7 int main() 8 { 9 int A[7]={4,5,6,7,0,1,2}; 10 int target; 11 cout<<"please input the target you want to search!"<<endl; 12 cin>>target; 13 int index=search(A,7,target); 14 if (index==-1) 15 { 16 cout<<"can't find the target!"<<endl; 17 } 18 else 19 cout<<"find it! the index is :"<<index<<endl; 20 return 0; 21 } 22 23 int search(int A[],int n,int target) 24 { 25 for (int i = 0; i < n; i++) 26 { 27 if (A[i]==target) 28 { 29 cout<<"find the target!"<<endl; 30 cout<<"the index is :"<<i<<endl; 31 return i; 32 } 33 } 34 return -1; 35 }
另一种解决办法
1 #include <iostream> 2 3 using namespace std; 4 5 int search2(int A[],int n,int target); 6 7 int main() 8 { 9 int A[7]={4,5,6,7,0,1,2}; 10 int target; 11 cout<<"please input the target you want to search!"<<endl; 12 cin>>target; 13 int index=search2(A,7,target); 14 if (index==-1) 15 { 16 cout<<"can't find the target!"<<endl; 17 } 18 else 19 cout<<"find it! the index is :"<<index<<endl; 20 return 0; 21 } 22 23 int search2(int A[],int n,int target) 24 { 25 int first =0,last =n; 26 while(first!=last) 27 { 28 const int mid =(first+last)/2; 29 if (A[mid]==target) 30 { 31 return mid; 32 } 33 if (A[first]<=A[last]) 34 { 35 if (A[first]<=target && target<A[mid]) 36 { 37 last=mid; 38 } 39 else 40 first=mid+1; 41 } 42 else 43 { 44 if (A[mid]<=target && target<A[last-1] ) 45 { 46 first=mid+1; 47 } 48 else 49 last=mid; 50 } 51 } 52 return -1; 53 }
4 search in roated sorted Array2
discript:
follow us for "search in roated sorted Array ":what if duplicates sre allowed?
would this sffect the run-time complexity ?how and why?
write a function to determine if a given target is in the array.
method 1 ,just as the same way in 4 ,O(n) in time complex,O(1) in the space complex.
要注意这个continue的使用,否则不能够度多个相同的数据。
同时也要注意到那个else i++的作用,负责不能够继续读下去,只能查询前两个;
1 #include <iostream> 2 3 using namespace std; 4 5 int search(int A[],int n,int target); 6 7 int main() 8 { 9 int A[7]={4,4,6,7,0,0,2}; 10 int target; 11 cout<<"please input the target you want to search!"<<endl; 12 cin>>target; 13 int index=search(A,7,target); 14 if (index==-1) 15 { 16 cout<<"can't find the target!"<<endl; 17 } 18 else 19 cout<<"find it! the index is :"<<index<<endl; 20 return 0; 21 } 22 23 int search(int A[],int n,int target) 24 { 25 int i=0; 26 while(i<n) 27 { 28 if (A[i]==target) 29 { 30 cout<<"find the target!"<<endl; 31 cout<<"the index is :"<<i<<endl; 32 i++; 33 continue; 34 return 0; 35 } 36 else 37 i++; 38 } 39 return -1; 40 }
第二种方法,虽然时间复杂度依然是O(n),空间复杂度是O(1),但是也提供了一种思路;
首先分析一下
允许重复元素,那么上一题中如果A[m]>=A[1],那么[1,m]中为递增序列的假设就不成立了,比如[1,3,1,1,1,]
如果A[m]>A[1]不能确定递增,那就把它拆分成两个条件:
若A[m]>A[1],则区间【1,m】一定递增;
若A[m]==A[1]确定不了,那就l++,继续下一步就行了;
1 #include <iostream> 2 3 using namespace std; 4 5 int search(int A[],int n,int target); 6 7 int main() 8 { 9 int A[7]={4,5,6,7,0,1,2}; 10 int target; 11 cout<<"please input the target you want to search!"<<endl; 12 cin>>target; 13 int index=search(A,7,target); 14 if (index==-1) 15 { 16 cout<<"can't find the target!"<<endl; 17 } 18 else 19 cout<<"find it! "<<endl; 20 return 0; 21 } 22 23 int search(int A[],int n,int target) 24 { 25 int first =0,last =n; 26 while(first!=last) 27 { 28 const int mid =(first+last)/2; 29 if (A[mid]==target) 30 { 31 return 0; 32 } 33 if (A[first]<A[last]) 34 { 35 if (A[first]<=target && target<A[mid]) 36 { 37 last=mid; 38 } 39 else 40 first=mid+1; 41 } 42 else if(A[first]>A[mid]) 43 { 44 if (A[mid]<=target && target<A[last-1] ) 45 { 46 first=mid+1; 47 } 48 else 49 last=mid; 50 } 51 else 52 first++; 53 } 54 return -1; 55 }
5 Median of two sorted arrays
there are two sorted arrays A,B of size m and n respectively. find the median of the two sorted arrays .the overal run time complexity should be O(log(m+n)).
首先只要解出来就好了,那么分配一个新的数组,大小是两个数组的大小和;
按照大小排序之后,很容易就求得了;时间复杂度O(n+m),空间复杂度O(1),因为需要的大小固定;
第二种方法是采用指针来实现;
其实如果不是规定了时间复杂度的话,很容易就能得到
下面我们先解决这个问题,不考虑时间复杂度的要求;
1 #include <iostream> 2 using namespace std; 3 4 int find_k(int A[],int m,int B[],int n,int k); 5 6 int main() 7 { 8 int A[4]={1,3,4,6}; 9 int B[6]={2,4,5,7,8,9}; 10 int m=find_k(A,4,B,6,3); 11 cout<<"the ans is "<<m<<endl; 12 return 0; 13 14 } 15 16 int find_k(int A[],int m,int B[],int n,int k) 17 { 18 if (m==0) 19 { 20 return B[n/2]; 21 } 22 if (n==0) 23 { 24 return A[n/2]; 25 } 26 27 28 int *p,*q; 29 p=A; 30 q=B; 31 int i=0; 32 int ans=0; 33 while(i<k) 34 { 35 if (*p<=*q) 36 { 37 ans=*p; 38 p++; 39 i++; 40 41 } 42 else 43 { 44 ans=*q; 45 q++; 46 i++; 47 } 48 } 49 return ans; 50 }
考虑时间复杂度的要求
方法如下:
1 #include <iostream> 2 using namespace std; 3 4 5 double findMedianSortedArrays(int A[],int m,int B[],int n); 6 7 int find_kth(int A[],int m,int B[],int n,int k); 8 9 int min(int a,int b); 10 11 12 int main() 13 { 14 int A[4]={1,3,4,6}; 15 int B[6]={1,2,4,5,6,8}; 16 int ans= findMedianSortedArrays(A,4,B,6); 17 cout<<"the meidan of two array is:"<<ans<<endl; 18 return 0; 19 } 20 21 double findMedianSortedArrays(int A[],int m,int B[],int n) 22 { 23 int total=m+n; 24 if (total & 0x1) 25 { 26 return find_kth(A,m,B,n,total/2+1); 27 } 28 else 29 return (find_kth(A,m,B,n,total/2)+find_kth(A,m,B,n,total/2+1))/2; 30 } 31 32 int find_kth(int A[],int m,int B[],int n,int k) 33 { 34 if (m>n) 35 { 36 return find_kth(B,n,A,m,k); 37 } 38 if (m==0) 39 { 40 return B[k-1]; 41 } 42 if (k==1) 43 { 44 return min(A[0],B[0]); 45 } 46 int ia=min(k/2,m),ib=k-ia; 47 if (A[ia-1]<B[ib-1]) 48 { 49 return find_kth(A+ia,m-ia,B,n,k-ia); 50 } 51 else if (A[ia-1]>B[ib-1]) 52 { 53 return find_kth(A,m,B+ib,n-ib,k-ib); 54 } 55 else 56 return A[ia-1]; 57 } 58 59 int min(int a,int b) 60 { 61 if (a<=b) 62 { 63 return a; 64 } 65 else 66 return b; 67 }