返回

在喧嚣世界中寻找宁静:极简主义数字配对

后端

引言

数字配对是一种常见的算法问题,它要求我们寻找满足特定条件的数字对。在本文中,我们将踏上极简主义之旅,探索如何查找和最小的 K 对数字。我们将从题目的核心概念开始,然后深入到算法的各个方面,并用清晰的示例和代码演示它的实现。

题目

给定两个以升序排列的整数数组 nums1nums2,以及一个整数 k。我们的任务是找到 k 对最小的数字,其中每一对都由一个来自 nums1 的数字和一个来自 nums2 的数字组成。

解题思路

为了解决这个问题,我们可以采用一种优雅的解决方案,它将我们带入极简主义数字配对的领域。首先,我们将两个数组中的所有元素合并到一个新的数组 nums 中。然后,我们对 nums 进行排序,确保数字按升序排列。

关键步骤

  1. 初始化 :我们创建一个优先级队列 pq,将 (nums[0] + nums[nums.length - 1], 0, nums.length - 1) 放入其中,其中 0nums.length - 1 分别表示 numsnums1nums2 中数字的下标。

  2. 迭代 :进入循环,直到 pq 为空或已经找到 k 对数字。

  3. 出队 :从 pq 中弹出顶部元素 (sum, i, j)

  4. 检查 :如果 ij 尚未到达 nums 的结尾,则将 (sum, i + 1, j)(sum, i, j - 1) 放入 pq 中,因为这些元素分别对应于 nums1 中的下一个数字与 nums2 中的当前数字之和,以及 nums2 中的下一个数字与 nums1 中的当前数字之和。

  5. 记录 :如果 ij 已到达 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 的情况。我们的算法将按照以下步骤进行:

  1. 初始化:pq = [(19, 0, 2)]
  2. 迭代:
    • 出队:(19, 0, 2)
    • 检查:ij 尚未到达 nums 的结尾,因此我们将 (18, 1, 2)(20, 0, 1) 加入 pq
    • 记录:无
  3. 迭代:
    • 出队:(18, 1, 2)
    • 检查:ij 尚未到达 nums 的结尾,因此我们将 (17, 2, 2)(19, 1, 1) 加入 pq
    • 记录:(7, 2)
  4. 迭代:
    • 出队:(17, 2, 2)
    • 检查:i 已到达 nums 的结尾,因此我们将 (7, 4) 添加到结果中。
    • 记录:无
  5. 停止,因为我们已经找到了 3 对最小的数字。

结论

在数字配对的极简主义世界中,我们探索了一种优雅而高效的算法,可以找到和最小的 K 对数字。通过结合优先级队列和有序合并,我们的解决方案有效且易于理解。利用本文提供的清晰示例和代码,您可以掌握此算法,并将其应用于您的编码挑战。当您下次需要解决数字配对问题时,请记住极简主义的力量,并轻松应对!