面试题之陈利人 两个数组中求第k小元素
2014-01-12 18:23
253 查看
两个数组中求第k小数
真言
幸福的人生是不存在的,什么叫幸福?不完美的完美就是幸福。
引言
陈利人先生的题目很有思考性,很喜欢。
题目
给两个同样长度排好序的数组,找出第k个最小的数。
思路
思路很清晰,借鉴与折半查找,不断减小查找范围。
举个例子吧,两个数组(a and b)如下(一共16个数),看看我们是怎么减小搜索范围的,我们找出第九小的数
第九小的数肯定在两个数组的前九个里,但是每个数组就八个数,所以没有减小范围。然后找出数组a的中间数,如下
再在数组b里折半查找这个数,如下
发现不存在,则返回最靠近查找数的数,如上。然后这时候我们发现这两个数以及其前面的数一共是5个,所以第六小数肯定不在刚才那个范围里,则缩小范围
缩小后,得到的范围如下,则查找第(6-5)小数,即第一小数,这时候就特简单了。
实验
代码
#include<iostream> using namespace std; // define size for array const int size = 20; // function declare to the problem int Super_bisearch(int * A,const int Asize,int * B,const int Bsize,const int k); // function declare to binary search int Bisearch(int *d,int length,int key ); // function main int main() { int * A = new int[size]; int * B = new int[size]; for(int i = 0;i<size;i++) { A[i] = 2*i; cout<<A[i]<<" "; B[i] = 2*i+5; cout<<B[i]<<" "; } cout<<endl; int i = 1; while( i <= size*2 ) { cout<<"第 "<<i<<" 小元素为 "<<Super_bisearch(A,size,B,size,i)<<endl; i++; } system("pause"); return 0; } // function define to the problem int Super_bisearch(int * A,const int Asize,int * B,const int Bsize,const int k) { if(A == NULL || B == NULL || Asize < 0 || Bsize <0 || k <= 0 || k > (Asize+Bsize)) { cout<<"exception of input super_bisearch"<<endl; return 1; } else if(Asize != Bsize) { cout<<"Asize != Bsize"<<endl; return 1; } int sa,sb,ba,bb; sa = 0; sb = 0; ba = (Asize < k)? Asize:k; bb = (Bsize < k)? Bsize:k; ba--;bb--; int ca ; int cb ; int number = k; ca = (sa+ba)/2; cb = Bisearch(B,Bsize,A[ca]); while( number > 2 &&(sa<ca || sb<cb)) { ca = (sa+ba)/2; cb = Bisearch(B,Bsize,A[ca]); if( number > ( ca + cb - sa - sb) ) { number = number - ( ca + cb - sa - sb ); sa = ca; sb = cb; if( ( ca + cb - sa - sb ) == 0) break; } else if( ( ca + cb - sa - sb) == number ) { return A[ca]>B[cb]?A[ca]:B[cb]; } else if( number < ( ca + cb - sa - sb) ) { ba = ca; bb = cb; } } int * d = new int[ba-sa+1+bb-sb+1]; int i = sa,j = sb,bit = 0; while(i <= ba && j <= bb) { if(A[i]<B[j]) d[bit++] = A[i++]; else d[bit++] = B[j++]; } while(i<=ba) d[bit++] = A[i++]; while(j<=bb) d[bit++] = B[j++]; return d[number-1]; } // function define to binary search int Bisearch(int *d,int length,int key ) { if( d == NULL && length <= 0 ) { cout<<"exception of input Bisearch"<<endl; return -1; } else{ int s = 0 ; int e = length-1 ; int c ; while(s < e) { c = ( s + e ) / 2; if( d[c] == key ) { return c; } else if( key < d[c] ) { e = c-1; } else if( key > d[c] ) { s = c; if( e-s == 1 && d[s]<d[e]) { return s; } } } return s; } }
相关文章推荐
- @陈利人 : #面试题#给定两个数组X和Y,元素都是正数。请找出满足如下条件的数对的数目: x^y > y^x,即x的y次方>y的x次方;x来自X数组,y来自Y数组
- 从两个有序数组的并集中寻找第k小元素
- 【极难】【二分查找】返回两个数组中第k小的元素
- [LeetCode题解]从两个有序数组的并集中寻找第k小元素
- 数据结构面试题总结4——数组:求两个有序数组中的共同元素
- 求两个有序数组的中位数或者第k小元素(转载)
- 查找两个已经排好序的数组的第k大的元素
- 谷歌面试题-两个数组合并后第k小的数字
- [面试题]设计一个算法找到数组中两个元素相加等于指定数的所有组合
- 求两个有序数组的中位数(扩展求第k大元素)
- 求两个有序数组的中位数和者第k小元素
- 杨氏矩阵第K小值/两个数组元素之和最小值
- 两个有序数组中找中位数或者第K大的元素
- 从两个有序数组的并集中寻找第k小元素
- 【面试题】数组中有两个元素出现了奇数次,其他元素出现了偶数次。找出这两个元素
- 查找两个已经排好序的数组的第k大的元素
- [各种面试题] 两个数组和的第K大
- 华为面试题(8分钟写出代码) 有两个数组a,b,大小都为n,数组元素的值任意,无序; 要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
- LeetCode--找到两个排序数组中第k大的元素
- Find K-th Smallest Pair Distance:查找数组元素中差值第K大的两个元素的差值