我正在尝试找到两个不同大小的排序数组的中位数。但有一些情况它不起作用,我无法弄清楚原因。我在下面列出了我的实现。
我确实在网上有类似的解决方案。但我刚刚开始学习算法,所以我想尽可能多地做自己。非常感谢您的帮助!
public double median(Point[] arr, int start, int end) {
int n = end - start + 1;
if (n % 2 == 0) {
return (double) (arr[start + (n/2)].getSz() + arr[start + (n/2) - 1].getSz())/2;
}
else {
return (double) arr[start + (n/2)].getSz();
}
}
public double getMedian(int aStart, int aEnd, int bStart, int bEnd) {
int m = aEnd - aStart + 1;
int n = bEnd - bStart + 1;
double median = 0;
if (m == 0 && n > 0) {
return median(arr2, 0, bEnd);
}
if (m > 0 && n == 0) {
return median(arr1, 0, aEnd);
}
if (m == 1 && n == 1) {
return (double) (arr1[0].getSz() + arr2[0].getSz())/2;
}
if (m == 2 && n == 2) {
median = (double) (Math.max(arr1[aStart].getSz(), arr2[bStart].getSz()) + Math.min(arr1[aEnd].getSz(), arr2[bEnd].getSz()))/2;
return median;
}
double m1 = median(arr1, aStart, aEnd);
double m2 = median(arr2, bStart, bEnd);
if (m1 == m2) {
return m1;
}
if (m1 < m2) {
if (m % 2 == 0) {
aStart = aStart + (m/2) - 1;
index = 1;
}
else {
index = 2;
aStart = aStart + m/2;
}
bEnd = bStart + n/2;
}
else {
if (n % 2 == 0) {
index = 3;
bStart = bStart + n/2 - 1;
}
else {
index = 4;
bStart = bStart + n/2;
}
aEnd = aStart + m/2;
}
return (getMedian(aStart, aEnd, bStart, bEnd));
}
以下是逻辑中断的示例:
arr1 = 6,20,28,29,36,41
arr2 = 14,15,33,47,53,66,79,98
正确中位数= 34.5
估计中位数= 31
答案 0 :(得分:1)
看起来算法中存在一些问题。
首先在几个地方使用0代替aStart和bStart:
if (m == 0 && n > 0) {
return median(arr2, ->0<-, bEnd);
}
if (m > 0 && n == 0) {
return median(arr1, ->0<-, aEnd);
}
if (m == 1 && n == 1) {
return (double) (arr1[->0<-].getSz() + arr2[->0<-].getSz())/2;
}
其次;在最后一个区块中,你必须小心地抛出高于中位数的数量。
if (m1 < m2) {
if (m % 2 == 0) {
aStart = aStart + (->m<-/2) - 1;
index = 1;
}
else {
index = 2;
aStart = aStart + ->m<-/2;
}
bEnd = bStart + ->n<- /2;
}
并且您也不得丢弃最接近中位数的中位数的数据。希望有所帮助。
答案 1 :(得分:0)
要获得两个排序数组 A 和 B 的中位数,您需要弄清楚如何将两个数组拆分为低部分和高部分,以便所有低部分元素都是&lt; =所有高部分元素,低部分和高部分中元素的总数是相同的(在1之内)。
低元素将包含来自 A 的一些 x 元素,以及(A.length + B.length)/ 2 - x 来自 B 的元素。
要查找 x ,您可以对 x 的可能值进行二进制搜索。设 MID =(A.length + B.length)/ 2 。然后,假设 x ,如果 A [x-1]> B [MID-x] ,则 x 太大。否则它不会太大。这个条件足以让你在每次迭代中将值的范围减少一半。
一旦你知道阵列的分割位置,你知道 max(A [x-1],B [MID-x-1])是低部分中的最高元素,并且 min(A [x],B [MID-x])是高部分中的最低元素,这就是计算中位数所需的全部内容。