有序数组a,b,找出a,b(合并为一个大的有序数组后)中第k个数

来源:互联网 发布:牛耳软件教育 编辑:程序博客网 时间:2024/04/30 06:05
//已知有序数组a,b,长度分别为m,n。找出a,b(合并为一个大的有序数组后)中第k个数。要求时间复杂度为o(log(m+n)).//当k = (m+n-1)/2时,若m+n为奇数,则第k个数即为中位数;若m+n为偶数,第k个数即为下中位数。/*#include <iostream>#include <math.h>using namespace std;int select_kth_num(int a[],int b[],int m,int n, int k){int index = -1; //存放第k个数的下标if (k>m+n || k<1){return -1;}else{int begin = 0;int end = m-1;int mid = (begin+end)/2;  //先在数组a里面查找;mid为下标,若m为奇数,则mid指向正中间那个数;若为偶数,mid指向的是上中位数// 则a中有mid个数小于a[mid]; 若a[mid]在b中刚好大于k-mid-1个数,则a[mid]为第k个数while (mid >= k)  // 此时a[mid]为a中至少是第k+1个数;不符合需缩小范围{end = mid-1;mid = (begin+end)/2;}while (begin <= end){mid = (begin+end)/2; while (mid >= k)  // 由于外层while每次结束时,begin或end有变化,再进入循环时的mid有可能大于k,因此仍需要缩小范围。{end = mid-1;mid = (begin+end)/2;}if (k-mid-1 == 0){if (a[mid]<=b[k-mid-1]){return a[mid];}else{if (a[mid]>b[k-mid-1])  //说明a,b中比a[mid]小的数的总个数大于k-1个,a[mid]取大了,应该在现在的位置的左边取{end = mid - 1;}else   //说明a,b中比a[mid]小的数的总个数小于k-1个,a[mid]取小了,应该在现在的位置的右边取{begin = mid + 1;}}}else if (k-mid-1 > 0 && k-mid-1 < n)   {if (a[mid]>=b[k-mid-2]&&a[mid]<=b[k-mid-1]){return a[mid];}else{if (a[mid]>b[k-mid-1])  //说明a,b中比a[mid]小的数的总个数大于k-1个,a[mid]取大了,应该在现在的位置的左边取{end = mid - 1;}else   //说明a,b中比a[mid]小的数的总个数小于k-1个,a[mid]取小了,应该在现在的位置的右边取{begin = mid + 1;}}}else  if ( k-mid-1 == n)  //b的长度刚好等于k-mid-1{if (a[mid]>=b[n-1])  // 此时只需a[mid] >= b[n-1]即可{return a[mid];}else{begin = mid+1;}}else//k-mid-1 > n ,此时超过了b中的长度,说明mid取小了{begin = mid+1;}}//a中没有找到,则在b中找begin = 0;end = n-1;mid = (begin+end)/2;while (mid >= k)  // 此时b[mid]为b中至少是第k+1个数;不符合需缩小范围{end = mid-1;mid = (begin+end)/2;}while (begin <= end){mid = (begin+end)/2; while (mid >= k)  // 由于外层while每次结束时,begin或end有变化,再进入循环时的mid有可能大于k,因此仍需要缩小范围。{end = mid-1;mid = (begin+end)/2;}if (k-mid-1 == 0){if (b[mid]<=a[k-mid-1]){return b[mid];}else{if (b[mid]>a[k-mid-1])  {end = mid - 1;}else   {begin = mid + 1;}}}else if (k-mid-1 > 0 && k-mid-1 < m){if (b[mid]>=a[k-mid-2]&&b[mid]<=a[k-mid-1]){return b[mid];}else{if (b[mid]>a[k-mid-1])  {end = mid - 1;}else  {begin = mid + 1;}}}else  if ( k-mid-1 == m)  //a的长度m刚好等于k-mid-1{if (b[mid]>=a[m-1])  // 此时只需b[mid] >= a[n-1]即可{return b[mid];}else{begin = mid+1;}}else  //k-mid-1 > m ,此时超过了a中的长度,说明mid取小了{begin = mid+1;}}}}int  main(){int a[1] = {5},b[6] = {1,2,3,4,6,7};int res;for (int i = 0;i < 7;i++){res = select_kth_num(a,b,1,6,i+1);cout<<res<<endl;}//res = select_kth_num(a,b,8,2,4);//cout<<res<<endl;system("pause");return 0;}

0 0