我在寻找本练习的解决方案时遇到了麻烦:
Given scores, an array of integers representing all test and assignment scores, your task is to return an array of integers where output[i] represents the median grade after all marks up to (and including) scores[i] have been entered. Your instructor is a generous marker, so they always round the median up to the nearest integer.
median* - The median of an N-element sequence is defined as follows: If N is odd, the median is the element which stands in the middle of the sequence after it is sorted. If N is even, the median is the average (mean) of the two "middle" elements of the sequence after it is sorted.
Example
•For scores = [100, 20, 50, 70, 45] the output should be medianScores(scores) = [100, 60, 50, 60, 50].
After each score is entered, the median is recalculated as follows:
◦For [100], the median is 100 since it's the only element.
◦For [20, 100], the median is (20 + 100)/2 = 60 since there's an even number of elements.
◦For [20, 50, 100], the median is 50 (middle element).
◦For [20, 50, 70, 100], the median is (50 + 70)/2 = 60(mean of the two middle elements).
◦For [20, 45, 50, 70, 100], the median is 50 again (middle element).
Input / Output
我一直在尝试获取有效的代码,到目前为止,如果数组的长度为奇数,但即使它的偶数返回错误结果,该代码也可以工作;
public static int[] getMedian(int[] arr){
int[] sortedArr = new int[arr.length];
int length = arr.length-1;
int odd = arr.length-1;
int even = arr.length-1;
for(int i=0;i<arr.length;i++) {
sortedArr[length] = arr[i];
Arrays.sort(sortedArr);
if (length % 2 == 0) {
arr[i] = sortedArr[odd];
odd--;
} else {
arr[i] = (sortedArr[even] + sortedArr[even - 1]) / 2;
even--;
}
length--;
}
return arr;
}
该算法通过将arr中的元素添加到sortedArr中来工作。对元素进行排序,然后检查sortedArr是偶数还是奇数。如果其偶数arr [i]成为中间元素,如果其奇数arr [i]是中间元素之和除以2。
请您帮忙。
答案 0 :(得分:1)
将数组复制到sortedArray时,您正在覆盖现有值。
public static void main(String[] args) {
int[] ret = getMedian(new int[]{100,20,50,70,45});
System.out.println(Arrays.toString(ret));
}
public static int[] getMedian(int[] arr) {
int[] sortedArr = new int[arr.length];
int[] retArr = new int[arr.length];
int len = 1;
int realLength = arr.length-1;
for (int i = 0; i < arr.length; i++) {
sortedArr[realLength-i] = arr[i];
Arrays.sort(sortedArr);
// arrays are accessed in reverse so adjust is needed using
// array length.
if (len % 2 == 1) {
// use middle value
retArr[i] = sortedArr[realLength-len/2];
} else {
// average middle values
retArr[i] = (sortedArr[realLength-len/2]
+ sortedArr[realLength-len/2 + 1]) / 2;
}
len++;
}
return retArr;
}
}
答案 1 :(得分:1)
未优化的解决方案。
首先是一种只计算数组中位数的方法:
/** Generous or not: one to round up, zero to round down. */
private static final int generous = 1;
private static int median(int[] arr) {
Arrays.sort(arr);
int mid = arr.length / 2;
if (mid + mid == arr.length) { // little optimized "is it even"
return (arr[mid-1] + arr[mid] + generous) / 2;
} else {
return arr[mid];
}
}
然后为每个子数组调用它:
// passed array will be (partially) sorted
private static int[] getMedian(int[] arr) {
int[] result = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
result[i] = median(Arrays.copyOfRange(arr, 0, i+1));
}
return result;
}
最优化:不创建子数组,只需传递要考虑的长度
private static int median(int[] arr, int len) {
Arrays.sort(arr, 0, len);
int mid = len / 2;
if (mid + mid == len) { // little optimized "is it even"
return (arr[mid-1] + arr[mid] + generous) / 2;
} else {
return arr[mid];
}
}
在getMedian()
中称为
result[i] = median(arr, i+1);
答案 2 :(得分:1)
为了提高效率,第一步是确定更好的算法。
让我们调用median[]
创建的数组。
我将使用两个堆:
left
或k/2
的最小值的最大堆k/2+1
直至第k个索引,取决于k
是偶数还是奇数。 right
的最小值堆k/2
直至第k个索引为止然后
if k is even, median[k] = (left.max() + right.min())/2
if k is odd, median[k] = left.max()
初始化:
left <- min (scores[0], scores[1])
right <- max (scores[0], scores[1])
然后,对于每个新值x = scores[k]
,您必须管理两个堆,具体取决于k
是偶数还是奇数,并取决于x
,{{1 }}和left.max()
。两个堆保持正确的大小非常重要。这意味着有时值会从一个堆移到另一个堆。
如果right.min()
是偶数(k
是奇数):
k-1
如果If x < left.max() then x -> left, left.max() -> right (corresponding value removed from left)
else: x -> right
为奇数:
k
全局复杂度:O(nlogn)
我不太了解Java。如果Java没有堆,我想您可以改用If x < right.min() then x -> left
else: x -> right, right.min() -> left (corresponding value removed from right)
。