【发布时间】:2016-03-10 06:45:14
【问题描述】:
有两个排序数组 A 和 B,大小分别为 m 和 n。找到两个排序数组的中位数。总体运行时间复杂度应为 O(log (m+n))。
我不明白计算 aMid 和 bMid 的公式。这些公式背后的逻辑是什么?
int aMid = aLen * k / (aLen + bLen); // a 的中间数
int bMid = k - aMid - 1; // b 的中间数
这是程序的链接。 http://www.programcreek.com/2012/12/leetcode-median-of-two-sorted-arrays-java/][1]
public static double findMedianSortedArrays(int A[], int B[]) {
int m = A.length;
int n = B.length;
if ((m + n) % 2 != 0) // odd
return (double) findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1);
else { // even
return (findKth(A, B, (m + n) / 2, 0, m - 1, 0, n - 1)
+ findKth(A, B, (m + n) / 2 - 1, 0, m - 1, 0, n - 1)) * 0.5;
}
}
public static int findKth(int A[], int B[], int k,
int aStart, int aEnd, int bStart, int bEnd) {
int aLen = aEnd - aStart + 1;
int bLen = bEnd - bStart + 1;
// Handle special cases
if (aLen == 0)
return B[bStart + k];
if (bLen == 0)
return A[aStart + k];
if (k == 0)
return A[aStart] < B[bStart] ? A[aStart] : B[bStart];
int aMid = aLen * k / (aLen + bLen); // a's middle count
// I AM STUCK HERE
int bMid = k - aMid - 1; // b's middle count
// make aMid and bMid to be array index
aMid = aMid + aStart;
bMid = bMid + bStart;
if (A[aMid] > B[bMid]) {
k = k - (bMid - bStart + 1);
aEnd = aMid;
bStart = bMid + 1;
} else {
k = k - (aMid - aStart + 1);
bEnd = bMid;
aStart = aMid + 1;
}
return findKth(A, B, k, aStart, aEnd, bStart, bEnd);
}
我从带有代码的 cmets 中得到了一些想法,这些公式是如何计算的,但仍然不明白向某人解释“为什么要使用这些公式”或者这些公式背后的逻辑是什么?
对于 int aMid = aLen * k / (aLen + bLen); // a 的中间数 作为 aMid = aLen / 2 --(i)
and k = (aLen + bLen)/2, -->2 = (aLen + bLen)/k
将 2 的值放入 equ (i)
所以 aMid = aLen/(aLen + bLen)/k== aLen *k/ (aLen+bLen)
对于 int bMid = k - aMid - 1; // b 的中间计数
aMid + bMid + 1 = k 必须满足才能得出 A[aMid] > B[bMid] 时的结论
至于为什么 aMid + bMid + 1 = k 显着:如果 A[aMid] 大于 B[bMid],你知道 A 中 A[aMid] 之后的任何元素都不能是第 k 个元素,因为B 中有太多元素低于它(并且会超过 k 个元素)。您还知道 B[bMid] 和 B[bMid] 之前的任何元素都不能是第 k 个元素,因为 A 中低于它的元素太少(在 B[bMid] 之前没有足够的元素是第 k 个元素)。
【问题讨论】:
-
解决问题的最佳方法是尝试自己解决问题。你会怎么做?如果您假设两个数组具有相同的数字分布,那么从中间开始的最佳猜测是什么?
-
您的第二行不正确。递归调用此方法时,
k可能不同。 -
@PeterLawrey 我试着自己做,但我完全不知道该怎么做。还有其他计算中位数的算法,我完全理解它们,但他们找到了两个相等数组的中位数。我喜欢这个,因为它是更通用的算法。第 2 行是不正确的?是的,你是对的,当递归调用此方法时,k 可能会有所不同。
-
你解释的第二行。您假设
k始终以相同的方式计算。 -
@peterLawrey 是的,你是对的,我的假设是错误的。