两个不同大小的排序数组的中位数
Median of two different sized sorted arrays
我试图找到两个不同大小的排序数组的中位数。但是在某些情况下它不起作用,我无法弄清楚原因。我在下面包含了我的实现。
我知道网上有类似的解决方案。但我才刚刚开始学习算法,所以想尽可能多地自己做。非常感谢您的帮助!
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, 25, 33, 47, 53, 66, 79, 98
正确的中位数 = 34.5
估计中位数 = 31
看起来算法中有一些问题。
首先在几个地方使用 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;
}
并且您也不能丢弃最接近中位数的值,其中中位数是根据偶数个数据计算的。希望对您有所帮助。
要获得两个排序数组 A 和 B 的中位数,您需要弄清楚如何将两个数组拆分为低部分和高部分,使得所有低部分元素<=所有高部分元素,且低部分和高部分的元素总数相同(1以内)。
低元素将由 x 个来自 A 和 (A.length + B.length)/2 - 来自 B.
的 x 个元素
要找到 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]) 是高部分中的最低元素,这就是计算中位数所需的全部内容。
我试图找到两个不同大小的排序数组的中位数。但是在某些情况下它不起作用,我无法弄清楚原因。我在下面包含了我的实现。
我知道网上有类似的解决方案。但我才刚刚开始学习算法,所以想尽可能多地自己做。非常感谢您的帮助!
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, 25, 33, 47, 53, 66, 79, 98
正确的中位数 = 34.5
估计中位数 = 31
看起来算法中有一些问题。
首先在几个地方使用 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;
}
并且您也不能丢弃最接近中位数的值,其中中位数是根据偶数个数据计算的。希望对您有所帮助。
要获得两个排序数组 A 和 B 的中位数,您需要弄清楚如何将两个数组拆分为低部分和高部分,使得所有低部分元素<=所有高部分元素,且低部分和高部分的元素总数相同(1以内)。
低元素将由 x 个来自 A 和 (A.length + B.length)/2 - 来自 B.
的 x 个元素要找到 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]) 是高部分中的最低元素,这就是计算中位数所需的全部内容。