问题:给一个排好序的数组arr[9]={1,3,5,7,19,23,22,33,100};再给某个数k,看它是否在此数组中,如果在,返回它的index,否则返回-1。
使用遍历一遍查找的方法,最坏的时间复杂度是O(n).(假如第一个就找到了,时间复杂度是O(1),但这没有意义。一般情况,很可能找不到而变成就坏的情况。所以计算最坏时间复杂度非常有现实意义。)
当然,这题使用二分查找,时间复杂度为O(logn)
代码如下:
View Code
#include <stdio.h> int binarySearch(int* arr, int start, int end, int n){ int mid = (start+end)/2; if(arr[mid]==n) return mid; if(start>end) return -1; if(arr[mid]>n){ binarySearch(arr,start,mid-1,n); }else{ binarySearch(arr,mid+1,end,n); } } int main(){ int arr[9]={1,3,5,7,19,23,22,33,100}; int k;//the one I want to search. for(k=0;k<15;k++){ int i = binarySearch(arr,0,8,k); if(i==-1) printf("k=%d not found!\n",k); else printf("The one is arr[%d]=%d\n",i,arr[i]); } return 0; }
此题的一个扩展问题是:Given two sorted arrays A, B of size m and n respectively. Find the k-th smallest element in the union of A and B. You can assume that there are no duplicate elements.
这题也能用二分吗?参考这个详解http://leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html
Ai和Bj分别代表它们各自近K个的地方,即i=(k-1)*m/(m+n) j=(k-1)*n(m+n);
如果Ai-1<Bj<Ai 那么Bj就是全部union的array的第k个了。同理,要检验一下Bj-1<Ai<Bj.
如果都不是,则判断Ai大还是Bj大,第k个肯定在它们之间,递归地查找它们之间的元素。
详细代码如下:
View Code
#include <stdio.h> #include <assert.h> #define INT_MIN -99999999 #define INT_MAX 99999999 int findKthSmallest(int A[], int m, int B[], int n, int k) { assert(m >= 0); assert(n >= 0); assert(k > 0); assert(k <= m+n); int i = (int)((double)m / (m+n) * (k-1)); int j = (k-1) - i; //这个编程style貌似挺有用,老外喜欢严谨点,时不时assert一下,好debug以及提醒自己 assert(i >= 0); assert(j >= 0); assert(i <= m); assert(j <= n); // invariant: i + j = k-1 // Note: A[-1] = -INF and A[m] = +INF to maintain invariant int Ai_1 = ((i == 0) ? INT_MIN : A[i-1]); int Bj_1 = ((j == 0) ? INT_MIN : B[j-1]); int Ai = ((i == m) ? INT_MAX : A[i]); int Bj = ((j == n) ? INT_MAX : B[j]); if (Bj_1 < Ai && Ai < Bj) return Ai; else if (Ai_1 <= Bj && Bj <= Ai) //have duplicate elements or not. return Bj; assert((Ai > Bj && Ai_1 > Bj) || (Ai < Bj && Ai < Bj_1)); // if none of the cases above, then it is either: if (Ai < Bj) // exclude Ai and below portion // exclude Bj and above portion return findKthSmallest(A+i+1, m-i-1, B, j, k-i-1); else /* Bj < Ai */ // exclude Ai and above portion // exclude Bj and below portion return findKthSmallest(A, i, B+j+1, n-j-1, k-j-1); } int main(){ int arr[9]={1,3,5,7,19,23,32,33,100}; int arr2[5]={2,4,6,8,20}; int i; for(i=1;i<10;i++){ int ans = findKthSmallest(arr,9,arr2,5,i); printf("%d\n",ans); } return 0; }

浙公网安备 33010602011771号