最近有这个问题:
编写一个函数,它接受一个数组数组(每个数组包含从最大到最小的数字)和一个数字(n)。返回n个最大的数字。
例如:
findLargest([[10,5,3,1],[9,8,7,6],[11,2,1,0]],5) => [11,10,9,8,7]
findLargest([[15,5,3,1],[10,8,7,6]],3) => [15,10,8]
在不复制或修改数组的情况下执行此操作(只需从中读取)。 优化时间复杂度。
我想出了这个,但对我的解决方案并不满意:
function findLargest(numberArrays, n ) {
var results = [];
var pointers = [];
for (var x = 0; x < numberArrays.length; x++) {
pointers.push(0);
}
while (results.length < n) {
var subMaxes = [];
for (var i = 0; i < pointers.length; i++) {
var point = pointers[i];
subMaxes.push(numberArrays[i][point]);
}
var max = Math.max.apply(null, subMaxes);
var indexOfMax = subMaxes.indexOf(max);
pointers[indexOfMax]++;
results.push(max);
}
return results;
}
我认为它是O(n ^ 2)....无论如何在O(n)中做到了吗?
答案 0 :(得分:1)
问题可以正式化(稍微调整)为Given a 2D array of dimension n x n, where each row is sorted in a decreasing order, find the largest k elements
对于最大的n
元素,时间复杂度为O(nlogn)
。 k
最大元素的过程解释如下:
从每一行构建第一个元素的最大堆:时间复杂度为O(n)
从堆中提取最大元素,并从提取元素所属的行中将一个元素插入到堆中。时间复杂度为O(logn)
在提取所需数量的元素下重复。
因此,提取最大数字的迭代需要O(logn)时间,并且需要预处理O(n)成本。
要提取k
元素,上述算法的时间复杂度为O(klogn)
答案 1 :(得分:0)
将所有数组合并为单个数组。这需要花费O(n)时间。
使用中位数算法算法查找新数组中的第k个最大元素。 O(n)时间。
遍历数组并获取大于或等于该元素的所有元素。这需要花费O(n)时间。
该算法在O(n)时间内运行。