/**
* Complexity:
* O (logn)
*
* @author javadeveloper
*/
class MedianOfTwoSortedArrays {
private MedianOfTwoSortedArrays() {}
private static boolean isMedian (int[] a1, int[] a2, int pos) {
if (pos == 0 || pos == (a1.length - 1)) return true;
return (a1[pos] >= a2[pos]) && (a1[pos] <= a2[pos + 1]);
}
/**
* Given two sorted arrays of same length it returns the median.
* If arrays are not of equal length throws the IllegalArgumentException.
* If arrays are not sorted the results can be unpredictable.
*
* @param a1 the first sorted array
* @param a2 the second sorted array
* @return the median of the two integers or null if no such median is found due to illegal input.
*/
public static Double median
(int[] a1,
int[] a2
) {
int lb = 0;
int hb = a1.length - 1;
while (lb <= hb) {
int a1Median = (lb + hb)/2;
int a2Median = (a2.length - 1) - a1Median;
if (isMedian(a1, a2, a1Median) || isMedian(a2, a1, a2Median)) {
return (a1[a1Median] + a2[a2Median])/2.0;
}
if (a1[a1Median] < a2[a2Median]) {
lb = a1Median + 1;
}
if (a1[a1Median] > a2[a2Median]) {
hb = a1Median - 1;
}
}
return null;
}
public static void main
(String[] args
) { int a1[] = {1, 1, 10, 10};
int a2[] = {5, 5, 5, 5};
System.
out.
println(median
(a1, a2
)); }
}
LyoqCiAqIENvbXBsZXhpdHk6CiAqIE8gKGxvZ24pCiAqIAogKiBAYXV0aG9yIGphdmFkZXZlbG9wZXIKICovCmNsYXNzIE1lZGlhbk9mVHdvU29ydGVkQXJyYXlzIHsKCiAgICBwcml2YXRlIE1lZGlhbk9mVHdvU29ydGVkQXJyYXlzKCkge30KCiAgICBwcml2YXRlIHN0YXRpYyBib29sZWFuIGlzTWVkaWFuIChpbnRbXSBhMSwgaW50W10gYTIsIGludCBwb3MpIHsKICAgICAgICBpZiAocG9zID09IDAgfHwgcG9zID09IChhMS5sZW5ndGggLSAxKSkgcmV0dXJuIHRydWU7CiAgICAgICAgcmV0dXJuIChhMVtwb3NdID49IGEyW3Bvc10pICYmIChhMVtwb3NdIDw9IGEyW3BvcyArIDFdKTsKICAgIH0KCgogICAgLyoqCiAgICAgKiBHaXZlbiB0d28gc29ydGVkIGFycmF5cyBvZiBzYW1lIGxlbmd0aCBpdCByZXR1cm5zIHRoZSBtZWRpYW4uCiAgICAgKiBJZiBhcnJheXMgYXJlIG5vdCBvZiBlcXVhbCBsZW5ndGggdGhyb3dzIHRoZSBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24uCiAgICAgKiBJZiBhcnJheXMgYXJlIG5vdCBzb3J0ZWQgdGhlIHJlc3VsdHMgY2FuIGJlIHVucHJlZGljdGFibGUuCiAgICAgKiAKICAgICAqIEBwYXJhbSBhMSAgICB0aGUgZmlyc3Qgc29ydGVkIGFycmF5CiAgICAgKiBAcGFyYW0gYTIgICAgdGhlIHNlY29uZCBzb3J0ZWQgYXJyYXkgCiAgICAgKiBAcmV0dXJuICAgICAgdGhlIG1lZGlhbiBvZiB0aGUgdHdvIGludGVnZXJzIG9yIG51bGwgaWYgbm8gc3VjaCBtZWRpYW4gaXMgZm91bmQgZHVlIHRvIGlsbGVnYWwgaW5wdXQuCiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgRG91YmxlIG1lZGlhbiAoaW50W10gYTEsIGludFtdIGEyKSB7CiAgICAgICAgaWYgKGExLmxlbmd0aCAhPSBhMi5sZW5ndGgpIHRocm93IG5ldyBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24oIlRoZSBhcmd1bWVudCB0aHJvd24gaXMgaWxsZWdhbCIpOwoKICAgICAgICBpbnQgbGIgPSAwOwogICAgICAgIGludCBoYiA9IGExLmxlbmd0aCAtIDE7CgogICAgICAgIHdoaWxlIChsYiA8PSBoYikgewogICAgICAgICAgICBpbnQgYTFNZWRpYW4gPSAobGIgKyBoYikvMjsKICAgICAgICAgICAgaW50IGEyTWVkaWFuID0gKGEyLmxlbmd0aCAtIDEpIC0gYTFNZWRpYW47CgogICAgICAgICAgICBpZiAoaXNNZWRpYW4oYTEsIGEyLCBhMU1lZGlhbikgfHwgaXNNZWRpYW4oYTIsIGExLCBhMk1lZGlhbikpIHsKICAgICAgICAgICAgICAgIHJldHVybiAoYTFbYTFNZWRpYW5dICsgYTJbYTJNZWRpYW5dKS8yLjA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChhMVthMU1lZGlhbl0gPCBhMlthMk1lZGlhbl0pIHsKICAgICAgICAgICAgICAgIGxiID0gYTFNZWRpYW4gKyAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoYTFbYTFNZWRpYW5dID4gYTJbYTJNZWRpYW5dKSB7CiAgICAgICAgICAgICAgICBoYiA9IGExTWVkaWFuIC0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAJaW50IGExW10gPSB7MSwgMSwgMTAsIDEwfTsKICAgICAgIAlpbnQgYTJbXSA9IHs1LCA1LCA1LCA1fTsKICAgICAgIAlTeXN0ZW0ub3V0LnByaW50bG4obWVkaWFuKGExLCBhMikpOwogICAgfQp9