I have implemented a working function that does it. But it is not very efficient because it copies a new copy in each call. I am having trouble converting it to using only a_start, a_end, b_start, b_end. I have tried a couple of ways to convert it, but none of them are working for all cases. How can I convert it so that it takes in a start and end pointers for both array a and b? I have tried the following and modified k-i-1 and k-j-1 so that it only takes in k, but did not work.
int m = a_right-a_left, n=b_right-b_left;
int i = (a_left+a_right)/2;
or int i = (int)((m* (k-1)) / (m+n) );
Below is my working code using a new copy of array each call.
public static int kthSmallest(int[] a, int[] b, int k) {
if (a.length==0)
return b[k-1];
else if (b.length==0)
return a[k-1];
else if (b.length<a.length)
return kthSmallest(b, a, k);
// make sure i + j = k - 1
int m = a.length, n=b.length;
int i = (int)((double)m / (m+n) * (k-1)); // make sure i won't be out of bounds
int j = k - 1 - i;
int bj_1 = 0, ai_1 = 0;
if (i==0) { ai_1 = Integer.MIN_VALUE; } // in case i = 0, outOfBound
else { ai_1 = a[i-1]; }
if (j==0) { bj_1 = Integer.MIN_VALUE; } // in case j = 0, outOfBound
else { bj_1 = b[j-1]; }
if (bj_1 < a[i] && a[i] < b[j]) // kth smallest found, b[j-1] < a[i] < b[j]
return a[i];
if (ai_1 < b[j] && b[j] < a[i]) // kth smallest found, a[i-1] < b[j] < a[i]
return b[j];
if ( a[i] < b[j] ) // if true, exclude a's lower bound (if 2 arrays merged, a's lower bound must
// reside before kth smallest, so also update k.
// also exclude b's upper bound, since they are all greater than kth element.
return kthSmallest(Arrays.copyOfRange(a, i+1, a.length), Arrays.copyOfRange(b, 0, j), k-i-1);
else
return kthSmallest(Arrays.copyOfRange(a, 0, i), Arrays.copyOfRange(b, j+1, b.length), k-j-1);
}