Open lxw124 opened 4 years ago
一般这种问题都不会让你调换数组的顺序,可以使用堆来解决,先创建一个最大堆,容量为k,再将前k个数放进去,然后将后续的数组元素放进去,如果大于等于堆顶元素则忽略,如果小于堆顶元素,则插入堆中。
function swap(arr, i, j) {
[arr[i], arr[j]] = [arr[j], arr[i]];
}
class MaxHeap {
constructor(arr = []) {
this.container = [];
if (Array.isArray(arr)) {
arr.forEach(this.insert.bind(this));
}
}
insert(data) {
const { container } = this;
container.push(data);
let index = container.length - 1;
while (index) {
let parent = Math.floor((index - 1) / 2);
if (container[index] <= container[parent]) {
break;
}
swap(container, index, parent);
index = parent;
}
}
extract() {
const { container } = this;
if (!container.length) {
return null;
}
swap(container, 0, container.length - 1);
const res = container.pop();
const length = container.length;
let index = 0,
exchange = index * 2 + 1;
while (exchange < length) {
// 如果有右节点,并且右节点的值大于左节点的值
let right = index * 2 + 2;
if (right < length && container[right] > container[exchange]) {
exchange = right;
}
if (container[exchange] <= container[index]) {
break;
}
swap(container, exchange, index);
index = exchange;
exchange = index * 2 + 1;
}
return res;
}
top() {
if (this.container.length) return this.container[0];
return null;
}
}
/**
* @param {number[]} arr
* @param {number} k
* @return {number[]}
*/
var getLeastNumbers = function(arr, k) {
const length = arr.length;
if (k >= length) {
return arr;
}
const heap = new MaxHeap(arr.slice(0, k));
for (let i = k; i < length; ++i) {
if (heap.top() > arr[i]) {
heap.extract();
heap.insert(arr[i]);
}
}
return heap.container;
};
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 示例 1:
输入:arr = [3,2,1], k = 2 输出:[1,2] 或者 [2,1] 示例 2:
输入:arr = [0,1,2,1], k = 1 输出:[0]