[路飞]_查找和最小的K对数字

340 阅读1分钟

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]

解题思路

暴力查找

没啥技术含量,直接循环最多 k2k^2次;返回前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

可以想象为二维数组;入下图; 111.001.jpeg

对比第一列,找到最小值,弹出;并将此列的下一位放在第一列;
继续对比第一列,找到最小值,弹出放到结果中,将此列的下一位放在第一列;

看动画演示

111.gif

静态图

111.001.jpeg

111.002.jpeg

111.003.jpeg

111.004.jpeg

111.005.jpeg

111.006.jpeg

111.007.jpeg

111.008.jpeg

111.009.jpeg

111.010.jpeg

111.011.jpeg

111.012.jpeg

111.013.jpeg

代码

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))
}