美文网首页算法
373. 查找和最小的 K 对数字

373. 查找和最小的 K 对数字

作者: 红树_ | 来源:发表于2023-07-09 18:37 被阅读0次

    参考373. 查找和最小的 K 对数字

    题目

    给定两个以 非递减顺序排列 的整数数组 nums1nums2 , 以及一个整数 k 。定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2

    请找到和最小的 k 个数对 (u1,v1), (u2,v2) ... (uk,vk)

    输入: 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个,使用优先队列小根堆模拟:假设i,0出堆则下一个可能的较小数对为i,1...n;所有可把所有的i,0入堆出堆后枚举j入堆,也可反过来把所有的0,j先入堆枚举i入堆。

    class Solution {
        public List<List<Integer>> kSmallestPairs(int[] nums1, int[] nums2, int k) {
            PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2)->{
                return nums1[o1[0]] + nums2[o1[1]] - nums1[o2[0]] - nums2[o2[1]];
            });
            List<List<Integer>> ans = new ArrayList<>();
            int m = nums1.length,n = nums2.length,maxLen = Math.min(m, k) ;
            for (int i = 0; i < maxLen; i++)pq.offer(new int[]{i,0});
            while (k-- > 0 && !pq.isEmpty()) {
                int[] idxPair = pq.poll();
                List<Integer> list = new ArrayList<>();
                list.add(nums1[idxPair[0]]);
                list.add(nums2[idxPair[1]]);
                ans.add(list);
                if (idxPair[1] + 1 < n) {
                    pq.offer(new int[]{idxPair[0], idxPair[1] + 1});
                }
            }
            return ans;
        }
    }
    

    复杂度分析

    • 时间复杂度:O(klogmin(n,k))n为数组长度,循环遍历k次得到k个数对,每次堆的操作时间复杂度为logmin(n,k)
    • 空间复杂度:O(min(n,k)),堆中最多存放的元素。

    相关文章

      网友评论

        本文标题:373. 查找和最小的 K 对数字

        本文链接:https://www.haomeiwen.com/subject/ljjsudtx.html