给定两个以升序排列的整数数组 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 <= 104
- -109 <= nums1[i], nums2[i] <= 109
nums1 , nums2 均为升序排列1 <= k <= 1000
解题思路
- 利用一个数组来保存
nums1 中每个元素对应的最小组合的 nums2 下标,这样每次只需要最多遍历 n 次就能获取剩下可用最小的组合,获取之后,对应的下标就加一,这样就可以防止重复获取。 - 所谓双指针,指的就是
f 数组的下标对应 nums1 的下标元素,而 f 数组中的元素值对应的就是 nums2 下标元素。 - 时间复杂度是
O(n * k) 的。
代码
func kSmallestPairs(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [[Int]] {
var res = [[Int]]()
let n = nums1.count, m = nums2.count
guard n > 0 && m > 0 else {
return []
}
var f = [Int](repeating: 0, count: n)
while res.count < k {
var cur = 0
for i in 1..<n {
if f[i] == m {
continue
}
if f[cur] == m || nums1[cur] + nums2[f[cur]] > nums1[i] + nums2[f[i]] {
cur = i
}
}
if f[cur] == m {
break
}
res.append([nums1[cur], nums2[f[cur]]])
f[cur] += 1
}
return res
}
|