Find k-th largest (or Median) in two sorted arrays

Problem: Find k-th largest (or Median) in two sorted arrays

 

 

Solution 1
=========

Suppose input array's are in the following fashion
A[] = {2, 3, 7, 12, 27, 81, 91}
b[] = {1, 25, 32, 74, 89}

1. Take two pointers ptr1 and ptr2 at start in A[] and B[]
2. if(A[i] > B[j])
j++;
else
i++;
3. if ( (i +j ) == k)
compare A[i] and B[j] and return the larger of them
else
repeat step2.

Time Complexity = O(k)

 

code:

int i=0;

int j=0;

 

while(i<A.length && j<B.length)

{

    if(i+j+2 == k){

      if(i == A.length) return B[j];

      else if (j == B.length) return A[i];

      else

        return (A[i]>=B[j]?A[i]:B[j]);

    }

 

    if(i == A.length)j++;

    else if (j == B.length)i++;

    else if(A[i]>=B[j])i++;

    else

      j++;

}

 


Solution2
==========

Idea = 
We have to find the median of first k elements of A and B and  k = 5

1.   The kth largest among the union of A[] and B[] would be in the first k elements of of A[] and b[]
2. Consider k elements from A[] and B[] which results in the following array
a[] = {2. 3, 7, 12, 27}
b[] = {1, 25, 32, 74, 89}

3. Compare (A[mid], B[mid])
if (A[mid] is GT)
{
For ArrayA  = We can skip a[mid]..a[k] elements since a[mid] is greater and all elements from a[0]..a[mid] are valid candidates for being the median; since A[mid] is the greater element no point considering bigger elements than that for the median
For Array B =  We can skip b[0]...b[mid] elements since b[mid] is less; so all elements less than are not valid candidates for being median.
}
4. Repeat Step3 till you are left with either 2 or 3 elements then you do a comparision and find kth largest.

Time Complexity = O(log k)

Example showing Solution 2
=========================

A[] = { 2, 3, 7, 12, 27}
B[] = {1, 25, 32, 75, 89}

After step2 i.e. k elements from both arrays
A[mid] = 7 and B[mid] = 32

B[mid] is Greater.

Now array becomes after step3
a[] = {7, 12, 27}
b[] = { 1, 25, 32}

a[mid] = 12 and b[mid] = 25
After step3 the arrays become
a[] = { 12, 27} -- skpping the left portion of smaller element array
b[] = { 1, 25} -- skipping the right portion of larger element array

Now a[mid] = 12 and b[mid] = 1
after step3 the array becomes
a[] = {12}
b[] = {1,25}

Find the median of 12, 1, 25 in O(1) which is 12 which is the 5th largest

 

code(find median):

median(int* A, int * B, int sa, int sb)

{

    int mid_a = sa/2-1;

    int mid_b = sb/2-1;

 

    if(sa == 0)return B[mid_b];

    else if(sb == 0)return A[mid_a];

    else if(A[mid_a] == B[mid_b])return A[mid_a];

 

    if(A[mid_a] > B[mid_b])

      return(A, B+mid_b+1, mid_a, (sb-mid_b-1));

    else{

      return(A+mid_a+1, B, (sa-mid_a-1),mid_b );

    }

 

}


another code in C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h>
/*
select:
gets two sorted positive integer arrays, a & b, with sizes sa & sb respectively,
and returns the k-th smallest element of their union.
smallest element is referenced with k = 1
returns -1 on error
*/

int   select ( int   * a ,   int   * b ,   int   sa ,   int   sb ,   int   k )   {
      int   ma   =   sa   <   k / 2   ?   sa   -   1   :   k / 2   -   1 ;
      int   mb   =   k   -   ma   -   2 ;
      if   ( sa   +   sb   <   k )
          return   - 1 ;
      if   ( sa   ==   0 )
          return   b [ k   -   1 ] ;
      if   ( sb   ==   0 )
          return   a [ k   -   1 ] ;
      if   ( k   ==   1 )
          return   a [ 0 ]   <   b [ 0 ]   ?   a [ 0 ]   :   b [ 0 ] ;
      if   ( a [ ma ]   ==   b [ mb ] )
          return   a [ ma ] ;
      if   ( a [ ma ]   <   b [ mb ] )
          return   select ( a   +   ma   +   1 ,   b ,   sa   -   ma   -   1 ,   mb   +   1 ,   k   -   ma   -   1 ) ;
      return   select ( a ,   b   +   mb   +   1 ,   ma   +   1 ,   sb   -   mb   -   1 ,   k   -   mb   -   1 ) ;
}

/*
median:
uses select to find the median of the union of a and b (where a and b are sorted
positive integer arrays of sizes sa and sb respectively.
*/

int   median ( int   * a ,   int   * b ,   int   sa ,   int   sb )   {
      int   m1 ,   m2 ;
      if   ( ( sa   +   sb )   %   2   ==   1 )
          return   select ( a ,   b ,   sa ,   sb ,   ( sa   +   sb ) / 2   +   1 ) ;
    m1   =   select ( a ,   b ,   sa ,   sb ,   ( sa   +   sb ) / 2 ) ;
    m2   =   select ( a ,   b ,   sa ,   sb ,   ( sa   +   sb ) / 2   +   1 ) ;
      return   ( m1   +   m2 )   /   2 ;
}

int   main ( )   {
      int   a [ 3 ]   =   { 2 ,   4 ,   6 } ;
      int   b [ 11 ]   =   { 1 ,   3 ,   5 ,   7 ,   13 ,   17 ,   22 ,   23 ,   24 ,   25 ,   31 } ;
      printf ( "/n   median is %d/n " ,   median ( a ,   b ,   3 ,   11 ) ) ;
      return   0 ;
}

 

源地址: http://inder-gnu.blogspot.com/2007/09/find-k-th-largest-in-two-sorted-arrays.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值