求两个有序数组的第k小元素

转载自:http://xiaobaoqiu.github.io/blog/2014/05/30/k-th-smallest-element-in-the-union-of-two-sorted-arrays/
两个已序数组的第k小元素
两个已序数组(从小到大)的第k小元素.数组分别记为A(长度m)和B(长度n).

Solutions

方法1

将两个数组merge成一个有序数组(m+n大小),再直接取第k个元素.

时间复杂度:O(m+n).

空间复杂度:O(m+n).

方法2

两个指针i和j分别从小到大遍历两个数组,代码大致如下:

i=0, j=0
while((i+j)<k && (i<m || j<n)){
    if(A[i] < B[j]) i++;
    else j++;
}
时间复

杂度:O(k).

空间复杂度:O(1).

方法3

利用方法2,我们发现,如果

B[j-1] < A[i] < B[j]

则,A[i]为第i+j+1小的元素,同理,如果

A[i-1] < B[j] < A[i]

则B[j]是第i+j+1小的元素.令

i+j+1 = k

i+j=k-1

则找到了我们需要的第k小元素.

下面是我们的方法:

二分搜索数组A,i的初值:

i = (int)((double)m / (m+n) * (k-1));   令j = k-1-i;

比较,如果 B[j-1] < A[i] < B[j] 则返回A[i]
如果 A[i-1] < B[j] < A[i] 则返回B[j];

步骤2未结束,则比较A[i]和B[j]

如果A[i]

int kthSmallest(int A[], int m, int B[], int n, int k) {

  int i = (int)((double)m / (m+n) * (k-1));
  int j = (k-1) - i;

  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)
    return Bj;

  if (Ai < Bj)
    return kthSmallest(A+i+1, m-i-1, B, j, k-i);
  else
    return kthSmallest(A, i, B+j+1, n-j-1, k-j);
}

时间复杂度:O(logm + logn)

空间复杂度:O(1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值