「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
373. 查找和最小的 K 对数字
给定两个以 升序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2 。
请找到和最小的 k 个数对 (u1,v1), (u2,v2) ... (uk,vk) 。
「示例1:」
输入: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
输出: [1,2],[1,4],[1,6]
解释: 返回序列中的前 3 对数:
[1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
「示例2:」
输入: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
输出: [1,1],[1,1]
解释: 返回序列中的前 2 对数:
[1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
「示例 3: 」
输入: nums1 = [1,2], nums2 = [3], k = 3
输出: [1,3],[2,3]
解释: 也可能序列中所有的数对都被返回:[1,3],[2,3]
「注意: 」
- 1 <= nums1.length, nums2.length <= 105
- -109 <= nums1[i], nums2[i] <= 109
- nums1 和 nums2 均为升序排列
- 1 <= k <= 1000
解题思路
1. 构建一个大顶堆
2. 循环两个数组,分别取出一个值,放入一个数组里面
3. 新数组与堆里面的元素做对比,看是否符合入堆条件,如果符合则进行入堆操作
4. 最后返回堆里的元素即可
代码实现
/**
* 373. 查找和最小的K对数字
* @param {number[]} nums1
* @param {number[]} nums2
* @param {number} k
* @return {number[][]}
*/
class BigHeap {
constructor(k) {
this.arr = []; // 初始化数组
this.size = 0; // 初始化长度
this.max = k; // 初始化最大值
}
push(val) { // 入堆操作
this.arr.push(val);
this.size++;
if (this.size > 1) {
let cur = this.size - 1,
parent = (cur - 1) >> 1;
while (cur > 0 && compare(this.arr[cur], this.arr[parent])) {
[this.arr[cur], this.arr[parent]] = [this.arr[parent], this.arr[cur]];
cur = parent;
parent = (cur - 1) >> 1;
}
}
if (this.size > this.max) this.pop();
}
pop() { // 弹出操作
this.arr[0] = this.arr.pop();
this.size--;
let cur = 0,
childl = 1,
childr = 2;
while (
(childl < this.size && compare(this.arr[childl], this.arr[cur])) ||
(childr < this.size && compare(this.arr[childr], this.arr[cur]))
) {
if (childr < this.size && compare(this.arr[childr], this.arr[childl])) {
[this.arr[childr], this.arr[cur]] = [this.arr[cur], this.arr[childr]];
cur = childr;
} else {
[this.arr[childl], this.arr[cur]] = [this.arr[cur], this.arr[childl]];
cur = childl;
}
childl = cur * 2 + 1;
childr = cur * 2 + 2;
}
}
top() { // 获取堆顶元素
return this.arr[0];
}
}
function compare(arr1, arr2) { // 比较
return arr1[0] + arr1[1] > arr2[0] + arr2[1];
}
var kSmallestPairs = function (nums1, nums2, k) {
const heap = new BigHeap(k); // 构建堆
for (let i = 0; i < nums1.length; i++) {
for (let j = 0; j < nums2.length; j++) {
let temp = [nums1[i], nums2[j]]; // 分别取出来两个数放入数组
if (heap.size < k || compare(heap.top(), temp)) { // 判断是否符合入堆条件
heap.push(temp); // 入堆
} else {
break;
}
}
}
return heap.arr; // 最后返回结果
};
如果你对这道题目还有疑问的话,可以在评论区进行留言;