题目
给定两个以升序排列的整数数组 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]
解题思路
暴力查找
没啥技术含量,直接循环最多 次;返回前K对数据即可
代码
var kSmallestPairs = function (nums1, nums2, k) {
const len1 = nums1.length
const len2 = nums2.length
const result = []
for(let i = 0 ; i < Math.min(len1,k) ; i++){
for(let j = 0 ; j < Math.min(len2,k);j++){
result.push([nums1[i],nums2[j]])
}
}
return result.sort((a, b) => a[0] + a[1] - b[0] - b[1]).slice(0, k);
}
优先级队列
示例1
nums1 = [1,1,2,4], nums2 = [1,2,3], k = 2
可以想象为二维数组;入下图;
对比第一列,找到最小值,弹出;并将此列的下一位放在第一列;
继续对比第一列,找到最小值,弹出放到结果中,将此列的下一位放在第一列;
看动画演示
静态图
代码
var kSmallestPairs = function (nums1, nums2, k) {
const len1 = nums1.length
const len2 = nums2.length
const result = []
const len1Index = Array(len1).fill(0)
while (result.length < k) {
let min = null
let minIndex = null
for (let i = 0; i < len1; i++) {
const x = nums1[i]
if (len1Index[i] >= len2) continue
const y = nums2[len1Index[i]]
if (min === null) {
minIndex = i
min = x + y
}
if (x + y < min) {
minIndex = i
min = x + y
}
}
result.push([nums1[minIndex], nums2[len1Index[minIndex]]])
len1Index[minIndex]++
}
return result.slice(0, Math.min(k, len2 * len1))
}