public class Main {
public static void main(String[] args) {
int[] a = new int[] {2,4};
int[] b = new int[] {1,3,5};
//找到第3大的数字
System.out.println(findKK(a, b, 3));
//找到中位数
System.out.println(findMid(a, b));
}
// 找到第k个
public static int findKK(int[] a, int[] b, int k) {
if(k == 0) {
return Math.min(a[0], b[0]);
}
return supFindKK(a, 0, a.length, b, 0, b.length, k);
}
public static int supFindKK(int[] a, int l1, int r1, int[] b, int l2, int r2, int num) {
if(num == 1) {
return Math.min(a[l1], b[l2]);
}
int ka = Math.min(num / 2, r1 - l1 + 1);
int kb = Math.min(num - ka, r2 - l2 + 1);
if(a[l1 + ka - 1] > b[l2 + kb - 1]) {
return supFindKK(a, l1, l1 + ka - 1, b, l2 + kb, r2, num - kb);
} else {
return supFindKK(a, l1 + ka, r1, b, l2, l2 + kb - 1, num - ka);
}
}
//找到中位数
public static double findMid(int[] a, int[] b) {
if(a.length > b.length) return findMid(b, a);
int n = a.length;
int m = b.length;
int l1 = 0, l2 = 0, r1 = 0, r2 = 0, c1, c2, lo = 0, hi = 2 * n;
while(lo <= hi) {
c1 = (lo + hi) / 2;
c2 = m + n - c1;
l1 = (c1 == 0) ? Integer.MIN_VALUE : a[(c1 - 1) / 2];
r1 = (c1 == 2 * n) ? Integer.MAX_VALUE: a[c1 / 2];
l2 = (c2 == 0) ? Integer.MIN_VALUE : b[(c2 - 1) / 2];
r2 = (c2 == 2 * m) ? Integer.MAX_VALUE : b[c2 / 2];
if(l1 > r2) {
hi = c1 - 1;
} else if(l2 > r1) {
lo = c1 + 1;
} else break;
}
return (Math.max(l1, l2) + Math.min(r1, r2)) / 2.0;
}
}