在喧嚣世界中寻找宁静:极简主义数字配对
2024-02-14 00:19:51
引言
数字配对是一种常见的算法问题,它要求我们寻找满足特定条件的数字对。在本文中,我们将踏上极简主义之旅,探索如何查找和最小的 K 对数字。我们将从题目的核心概念开始,然后深入到算法的各个方面,并用清晰的示例和代码演示它的实现。
题目
给定两个以升序排列的整数数组 nums1
和 nums2
,以及一个整数 k
。我们的任务是找到 k
对最小的数字,其中每一对都由一个来自 nums1
的数字和一个来自 nums2
的数字组成。
解题思路
为了解决这个问题,我们可以采用一种优雅的解决方案,它将我们带入极简主义数字配对的领域。首先,我们将两个数组中的所有元素合并到一个新的数组 nums
中。然后,我们对 nums
进行排序,确保数字按升序排列。
关键步骤
-
初始化 :我们创建一个优先级队列
pq
,将(nums[0] + nums[nums.length - 1], 0, nums.length - 1)
放入其中,其中0
和nums.length - 1
分别表示nums
中nums1
和nums2
中数字的下标。 -
迭代 :进入循环,直到
pq
为空或已经找到k
对数字。 -
出队 :从
pq
中弹出顶部元素(sum, i, j)
。 -
检查 :如果
i
和j
尚未到达nums
的结尾,则将(sum, i + 1, j)
和(sum, i, j - 1)
放入pq
中,因为这些元素分别对应于nums1
中的下一个数字与nums2
中的当前数字之和,以及nums2
中的下一个数字与nums1
中的当前数字之和。 -
记录 :如果
i
或j
已到达nums
的结尾,则将(nums[i], nums[j])
添加到结果列表中,因为这表示我们已经找到了一对最小的数字。
代码实现
import java.util.PriorityQueue;
import java.util.ArrayList;
public class MinKPairs {
public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
PriorityQueue<List<Integer>> pq = new PriorityQueue<>((a, b) -> a.get(0) - b.get(0));
List<List<Integer>> result = new ArrayList<>();
int m = nums1.length, n = nums2.length;
if (m == 0 || n == 0 || k == 0) return result;
pq.offer(Arrays.asList(nums1[0] + nums2[n - 1], 0, n - 1));
while (!pq.isEmpty() && result.size() < k) {
List<Integer> cur = pq.poll();
result.add(Arrays.asList(nums1[cur.get(1)], nums2[cur.get(2)]));
if (cur.get(1) + 1 < m) pq.offer(Arrays.asList(nums1[cur.get(1) + 1] + nums2[cur.get(2)], cur.get(1) + 1, cur.get(2)));
if (cur.get(2) - 1 >= 0) pq.offer(Arrays.asList(nums1[cur.get(1)] + nums2[cur.get(2) - 1], cur.get(1), cur.get(2) - 1));
}
return result;
}
}
示例
考虑 nums1 = [1, 7, 11]
和 nums2 = [2, 4, 6]
,k = 3
的情况。我们的算法将按照以下步骤进行:
- 初始化:
pq = [(19, 0, 2)]
- 迭代:
- 出队:
(19, 0, 2)
- 检查:
i
和j
尚未到达nums
的结尾,因此我们将(18, 1, 2)
和(20, 0, 1)
加入pq
。 - 记录:无
- 出队:
- 迭代:
- 出队:
(18, 1, 2)
- 检查:
i
和j
尚未到达nums
的结尾,因此我们将(17, 2, 2)
和(19, 1, 1)
加入pq
。 - 记录:
(7, 2)
- 出队:
- 迭代:
- 出队:
(17, 2, 2)
- 检查:
i
已到达nums
的结尾,因此我们将(7, 4)
添加到结果中。 - 记录:无
- 出队:
- 停止,因为我们已经找到了 3 对最小的数字。
结论
在数字配对的极简主义世界中,我们探索了一种优雅而高效的算法,可以找到和最小的 K 对数字。通过结合优先级队列和有序合并,我们的解决方案有效且易于理解。利用本文提供的清晰示例和代码,您可以掌握此算法,并将其应用于您的编码挑战。当您下次需要解决数字配对问题时,请记住极简主义的力量,并轻松应对!