我使用Medians of Medians实现了nth_number选择算法。 在wikipedia上,它声明它的空间复杂度为O(1)
我必须将中位数存储在一个临时数组中,以便找到这些中位数的中位数。如果不使用任何额外的内存,你怎么能这样做?如果它不算增加其空间复杂性,请解释。
function nth_number(v, n) {
var start = 0;
var end = v.length - 1;
var targetIndex = n - 1;
while(true) {
var medians = []; /* Extra memory. */
/* Divide our array into groups of 5s. Find a median within each */
for(var i = start; i <= end; i += 6) {
if(i + 5 < end)
medians.push(findMedian(v, i, i + 5));
else
medians.push(findMedian(v, i, end));
}
var median = findMedian(medians, 0, medians.length - 1); /* Find the median of all medians */
var index = partition(v, median, start, end);
if(index === targetIndex) {
console.log(median);
return median;
}
else {
if(index < targetIndex) {
start = index + 1;
targetIndex -= index;
}
else {
end = index - 1;
}
}
}
}
答案 0 :(得分:3)
选择算法需要重新排列输入向量,因为它会执行一系列分区。因此,假设可以重新排列输入向量以便找到中位数是合理的。
一种简单的可能策略是交错五个组,而不是使它们连续。因此,如果向量具有N == 5K
个元素,则五个组为:
(0, k, 2k, 3k, 4k)
(1, k+1, 2k+1, 3k+1, 4k+1)
(2, k+2, 2k+2, 3k+2, 4k+2)
...
(k-1, 2k-1, 3k-1, 4k-1, 5k-1)
然后当你找到一组五的中位数时,你将它与组中的第一个元素交换,这意味着中位数的向量将最终成为重新排列的向量的第一个k
元素。