Question:

Given two sorted arrays A, B of size m and n respectively. Find the k-th smallest element in the union of A and B. You can assume that there are no duplicate elements.


http://leetcode.com/2011/01/find-k-th-smallest-element-in-union-of.html


A special case: Median of two sorted arrays

https://oj.leetcode.com/problems/median-of-two-sorted-arrays/

http://leetcode.com/2011/03/median-of-two-sorted-arrays.html


// Option A: Two pointers
//
public int kMin(int[] A, int[] B, int k)
{
    int a = 0; // [0, A.length - 1]
    int b = 0; // [0, B.length - 1]
    
    int r = -1;
    for (int i = 0 ; i < k ; i ++)
    {
        int va = safeValue(A, a);
        int vb = safeValue(B, b);
        if (va < vb)
        {
            r = va;
            a ++;
        }
        else
        {
            r = vb;
            b ++;
        }
    }
    return r;
}

private int safeValue(int[] A, int i)
{
    if (i < 0 || i >= A.length)
        return Integer.MIN_VALUE;
    return A[i];
}


A Binary Search solution:

// Given A[i] and B[j]
// If B[j-1] < A[i] < B[j]
//
// A[i] must be the (i + j + 1)th min number
//
public int kMin(int[] A, int alow, int ahigh,
                int[] B, int blow, int bhigh,
                int k)
{
    // Assumptions...
    
    int i = selectI(A, alow, ahigh, B, blow, bhigh, k);
    int j = (k - 1) - 1;
    
    int Ai_1 = i <= 0 ? Integer.MIN_VALUE : A[i - 1];
    int Ai = i >= A.length ? Integer.MAX_VALUE : A[i];
    
    int Bj_1 = j <= 0 ? Integer.MIN_VALUE : B[j - 1];
    int Bj = j >= B.length ? Integer.MAX_VALUE : B[j];
    
    if (Bj_1 < Ai && Ai < Bj)
        return Ai;
    
    if (Ai_1 < Bj && Bj < Ai)
        return Bj
        
    // Now, it must be
    // Ai < Bj_1 < Bj
    // or
    // Bj < Ai_1 < Ai
    
    if (Ai < Bj) // Target must be in [Ai+1, Ahigh] X [Blow, Bj-1]
    {
        return kMin(A, i + 1, ahigh, B, blow, j - 1, k);
    }
    else
    {
        return kMin(A, alow, i - 1, B, j + 1, bhigh, k);
    }
}

// A methods determine i for A[i]
// j in B[j] would be (k - 1) - i
// The max value of i is k - 1.
private int selectI(int[] A, int alow, int ahigh,
                    int[] B, int blow, int bhigh,
                    int k)
{
    // Just choosing the middle number in A.
    int i = alow + (ahigh - alow) / 2;
    i = Math.min(i, k - 1);
    return i;
}