62,623
社区成员
发帖
与我相关
我的任务
分享// 原先的有点错误 这个已经更正过了
// 以下的算法并没有考虑序列中有重复的情况
public static int fd(int[] arrA, int al, int ar, int[] arrB, int bl, int br, int k) {
int am = (ar - al) / 2 + al;
int bm = (br - bl) / 2 + bl;
// am,bm,k都是从0开始计数的 所以比较时am+bm+2,k+1
if( am+bm+2 < k+1 ) { // am+bm+2 < k+1 可以得出k的在arrA[am]之后 或者在arrB[bm]之后
if( arrA[am+1] < arrB[bm+1] ) { // 如果直接比较arrA[am]和arrB[bm],根本不知道后面的
// 情况,arrA[am]<arrB[bm]时,有可能arrA[am+1]>arrB[bm]
if( ar-am == 1 ) am = ar; // ar前面作为中间位置,但实际B中有比arrA[ar]大的数,所以要回到那位置
return fd(arrA, am, ar, arrB, bl, br, k);
}
if( br-bm == 1 ) bm = br;
return fd(arrA, al, ar, arrB, bm, br, k);
} else if( am+bm+2 == k+1 ) {
if( arrA[am] == arrB[bm] ) return arrA[am];
if( arrA[am] < arrB[bm] ) {
if( bm==0 || arrA[am]>=arrB[bm-1] ) return arrB[bm];
if( arrA[am+1] < arrB[bm] ) return fd(arrA, am, ar, arrB, bl, bm, k);
else return arrB[bm];
}
// arrA[am] > arrB[bm]
if( am==0 || arrA[am-1]<=arrB[bm] ) return arrA[am];
if( arrA[am] > arrB[bm+1] ) return fd(arrA, al, am, arrB, bm, br, k);
else return arrA[am];
} else { // am+bm+2 > k+1
if( arrA[am] < arrB[bm] ) return fd(arrA, al, ar, arrB, bl, bm, k);
return fd(arrA, al, am, arrB, bl, br, k);
}
}import java.util.Scanner;
public class Main {
public static int fd(int[] arrA, int al, int ar, int[] arrB, int bl, int br, int k) {
int am = (ar - al) / 2 + al;
int bm = (br - bl) / 2 + bl;
if( am+bm < k ) {
if( arrA[am+1] < arrB[bm+1] ) {
if( ar-am == 1 ) am = ar;
return fd(arrA, am, ar, arrB, bl, br, k);
}
if( br-bm == 1 ) bm = br;
return fd(arrA, al, ar, arrB, bm, br, k);
} else if( am+bm == k ) {
if( arrA[am] == arrB[bm] ) return arrA[am];
if( arrA[am] < arrB[bm] ) {
if( arrA[am] >= arrB[bm-1] ) return arrA[am];
if( arrA[am+1] < arrB[bm] ) return fd(arrA, am, ar, arrB, bl, bm, k);
else return arrB[bm];
}
// arrA[am] > arrB[bm]
if( arrA[am-1] <= arrB[bm] ) return arrB[bm];
if( arrA[am] > arrB[bm+1] ) return fd(arrA, al, am, arrB, bm, br, k);
else return arrA[am];
} else { // am+bm > k
if( arrA[am] < arrB[bm] ) return fd(arrA, al, ar, arrB, bl, bm, k);
return fd(arrA, al, am, arrB, bl, br, k);
}
}
public static int findKMax(int[] arrA, int[] arrB, int k) {
// 处理零界情况 减少复杂度
if( arrA[arrA.length-1] < arrB[0] ) {
if( k < arrA.length ) return arrA[k];
else return arrB[k-arrA.length];
}
if( arrB[arrB.length-1] < arrA[0] ) {
if( k < arrB.length ) return arrB[k];
else return arrA[k-arrB.length];
}
if( k<arrA.length && arrA[k]<arrB[0] ) return arrA[k];
if( k<arrB.length && arrB[k]<arrA[0] ) return arrB[k];
if( k>arrA.length && arrB[k-arrA.length]>=arrA[arrA.length-1] ) return arrB[k-arrA.length];
if( k>arrB.length && arrA[k-arrB.length]>=arrB[arrB.length-1] ) return arrA[k-arrB.length];
return fd(arrA, 0, arrA.length-1, arrB, 0, arrB.length-1, k);
}
public static void main(String[] args) throws Exception {
int[] arrA = new int[10];
int[] arrB = new int[10];
for(int i = 0; i < 10; i++) {
arrA[i] = i;
arrB[i] = i + 3;
}
// Scanner scanner = new Scanner(System.in);
// while(true) {
// int d = scanner.nextInt();
// System.out.printf("d = %d, result = %d\n", d, findKMax(arrA, arrB, d));
// }
for(int i = 0; i < 20; i++)
System.out.printf("i = %d, result = %d\n", i, findKMax(arrA, arrB, i));
}
}