这个大顶堆,这两天都在看这个大顶堆,小顶堆,我看题解有几个大顶堆能看懂,但是他们的代码都提交超时,找了一个不超时的,比这写了一遍,中间用了 位运算符,然后我看不懂了.. 代码如下
/*
* @lc app=leetcode.cn id=373 lang=javascript
*
* [373] 查找和最小的 K 对数字
*/
// @lc code=start
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @param {number} k
* @return {number[][]}
*/
var kSmallestPairs = function (nums1, nums2, k) {
const pq = new Heap([], (a, b) => a[0] + a[1] < b[0] + b[1]);
for (const num1 of nums1) {
for (const num2 of nums2) {
const item = [num1, num2];
pq.push(item);
if (pq.size > k) {
// 引用相同 说明后面的数字都会出队 所以可以提前推出
if (pq.pop() === item) {
break;
}
}
}
}
return pq.getData()
};
// 最大堆
class Heap {
constructor(data, cmp) {
this.data = [null].concat(data);
this.cmp = cmp;
// 这个>> 目前还是理解不了啊
for (let i = data.length >> 1; i > 0; i--) { this.down(i) }
}
get size() {
return this.data.length - 1;
}
get top() {
return this.data[1];
}
// 返回1以后的
getData() {
return this.data.slice(1)
}
swap(i, j) {
[this.data[i], this.data[j]] = [this.data[j], this.data[i]];
}
up(i) {
if (i <= 1) {
return;
}
const p = i >> 1;
if (this.cmp(this.data[p], this.data[i])) {
this.swap(i, p);
this.up(p);
}
}
down(i) {
let j = i;
const n = this.data.length;
if (i > n - 1) {
return;
}
const l = i << 1, r = l + 1;
if (l < n && this.cmp(this.data[i], this.data[l])) {
i = l;
}
if (r < n && this.cmp(this.data[i], this.data[r])) {
i = r;
}
if (j !== i) {
this.swap(i, j);
this.down(i);
}
}
push(item) {
this.up(this.data.push(item) - 1)
}
pop() {
this.swap(1, this.data.length - 1);
const res = this.data.pop();
this.down(1);
return res;
}
}
// @lc code=end