AB有序数组长度可以不同,元素可以重复,求第k大

问题:给定一个有序(非降序)数组A和一个有序(非降序)数组B,可含有重复元素,求两个数组合并结果中的第k(k>=0)个数字。
这个题目出现了两个数组,有序的,不管怎样我们就应该首先考虑二分查找是否可行。若使用顺序查找,时间复杂度最低为O(k),就是类似归并排序中的归并过程。使用用二分查找时间复杂度为O(logM+logN)。二分查找的具体实现过程请参考实现代码与注释。
[cpp]  view plain copy
  1. int findKthIn2SortedArrays(int A[], int m, int B[], int n, int k)  
  2. {  
  3.     if(m <= 0) // 数组A中没有元素,直接在B中找第k个元素  
  4.         return B[k];  
  5.     if(n <= 0) // 数组B中没有元素,直接在A中找第k个元素  
  6.         return A[k];  
  7.     int i = (m-1)>>1; // 数组A的中间位置  
  8.     int j = (n-1)>>1; // 数组B的中间位置  
  9.     if(A[i] <= B[j])  // 数组A的中间元素小于等于数组B的中间元素  
  10.     {  
  11.         /* 
  12.         设x为数组A和数组B中小于B[j]的元素数目,则i+1+j+1小于等于x, 
  13.         因为A[i+1]到A[m-1]中还可能存在小于等于B[j]的元素; 
  14.         如果k小于i+1+j+1,那么要查找的第k个元素肯定小于等于B[j], 
  15.         因为x大于等于i+1+j+1;既然第k个元素小于等于B[j],那么只 
  16.         需要在A[0]~A[m-1]和B[0]~B[j]中查找第k个元素即可,递归调用下去。 
  17.         */  
  18.         if(k < i+1+j+1)  
  19.         {  
  20.             if(j > 0)  
  21.                 return findKthIn2SortedArrays(A, m, B, j+1, k);  
  22.             else // j == 0时特殊处理,防止死循环  
  23.             {  
  24.                 if(k == 0)  
  25.                     return min(A[0], B[0]);  
  26.                 if(k == m)  
  27.                     return max(A[m-1], B[0]);  
  28.                 return A[k] < B[0] ? A[k] : max(A[k-1], B[0]);  
  29.             }  
  30.         }  
  31.         /* 
  32.         设y为数组A和数组B中小于于等于A[i]的元素数目,则i+1+j+1大于等于y; 
  33.         如果k大于等于i+1+j+1,那么要查找到第k个元素肯定大于A[i],因为 
  34.         i+1+j+1大于等于y;既然第k个元素大于A[i],那么只需要在A[i+1]~A[m-1] 
  35.         和B[0]~B[n-1]中查找第k-i-1个元素,递归调用下去。 
  36.         */  
  37.         else  
  38.             return findKthIn2SortedArrays(A+i+1, m-i-1, B, n, k-i-1);  
  39.     }   
  40.     // 如果数组A的中间元素大于数组B的中间元素,那么交换数组A和B,重新调用即可  
  41.     else  
  42.         return findKthIn2SortedArrays(B, n, A, m, k);  
  43. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值