前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >每日打卡 373. 查找和最小的K对数字

每日打卡 373. 查找和最小的K对数字

作者头像
程序员小王
发布2020-07-22 14:59:49
6290
发布2020-07-22 14:59:49
举报
文章被收录于专栏:架构说

“Yesterday I was clever, so I wanted to change the world. Today I am wise, so I am changing Myself."

昨天的我聪明,想去改变这个世界。今天的我智慧,正在改进自我。

一、描述

代码语言:javascript
复制
You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.

Define a pair (u,v) which consists of one element from the first array and one element from the second array.

Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.

给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k。
 
定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2。
找到和最小的 k 对数字 (u1,v1), (u2,v2) ... (uk,vk)。

Example 1:

Input: nums1 = [1,7,11], nums2 = [2,4,6], k = 3
Output: [[1,2],[1,4],[1,6]] 
Explanation: The first 3 pairs are returned from the sequence: 
             [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]

思考 60秒 。。。

思考 60秒 。。

这个题目试着这里开始入手

算法五个重要的特征:

  • 输入项,输出项(题目已经给了)
  • 可行性(复杂问题转化成熟悉子问题)
  • 有穷性(在算法描述体现)
  • 确切性(在算法描述体现)

二、思路

最迷惑地方 pair (u,v)

题目告诉你 2个有序数组,求top k 不是 从2个有序数组获取一个记录就可以了。

想想暴力破解,是全部组合**(uk,vk)** ,我们可以暴力枚举全部的n1*n2对数字

熟悉子问题:

问:和最小的 k对数字,一定来两个以升序排列的整形数组,前面k个吗?

答:

最好情况k=1,最坏情况 k=n+m

k不一定小于 n或者m Input: nums1 = [10,20,30], nums2 = [1,2], k = 3

问:和最小的 k对数字,移动多少个可能 n+m

回答:错误,n*m个 。下图。

必须全部遍历,不是通过公式直接定位的。

问:在不全部遍历情况下,如何求top k

原问题转换成在n1个升序队列中,查找最小的前K对数字

  • 转换过程 k --->(n,m) -->n*m --->k 成在n1个升序队列中,查找最小的前K对数字
描述
  1. 一次性构造小顶堆
  2. 循环k次
测试bug

一个小错误:你发现了吗?

for (int i=k;i>0 && !priorityQueue.empty();k--) 有可能是死循环。i根本没有发送变化

三、代码

  • 放轻松,虽然是c++实现,拒绝奇技淫巧,通俗易懂。
代码语言:javascript
复制
// @lc code=start
class Solution
{
public:
    //找到和最小的 k 对数字
    //Solution1 找到全部组合n*m,然后排序。
    //Solution2 利用堆,在不枚举出全部数对的情况下
    //原问题转换成在n1个升序队列中,查找最小的前K对数字
    //Time  O(KlogN)
    vector<vector<int>> kSmallestPairs(vector<int> &nums1, vector<int> &nums2, int k)
    {
        int rows = nums1.size();
        int cols = nums2.size();
        vector<vector<int>> topK; //输出结果
        if (rows == 0 || cols == 0)
            return topK;

        // auto cmp = [&nums1, &nums2](pair<int, int> &a, pair<int, int> &b) {
        //     return (nums1[a.first] + nums2[b.second]) > (nums1[a.first] + nums2[b.second]);
        // }; //(3,(0,0)) (9,(1,0))  构造小顶堆

        auto cmp = [&nums1, &nums2](const pair<int, int> &a, const pair<int, int> &b) { return nums1[a.first] + nums2[a.second] > nums1[b.first] + nums2[b.second]; };

        priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(cmp)> priorityQueue(cmp);

        //假设nums1每个元素和 有序数组nums1相加后,产生n个有序数组.
        //{3,5.7}
        //{9.11.13}
        //{13,15,17}
        //然后组成n×m升序矩阵。

        //插入n个有序数组中的一个元素
        for (int i = 0; i < rows; i++)
        {
            priorityQueue.emplace(i, 0);
        }

        //找到和最小的 k 对数字 
        while (k > 0 && !priorityQueue.empty())
        {
            k--; //每次比较获取最小的一个元素,类比合并2个有序链表。
            pair<int, int> temp = priorityQueue.top();
            priorityQueue.pop(); //获取一个记录
            cout << nums1[temp.first] << ":" << nums2[temp.second] << endl;
            if (temp.second + 1 < cols)
            {
                cout << nums1[temp.first] << " insert " << nums2[temp.second + 1] << endl;
                priorityQueue.emplace(temp.first, temp.second + 1); //列+1
            }

            vector<int> item;
            item.push_back(nums1[temp.first]);
            item.push_back(nums2[temp.second]);

            topK.push_back(item);
        }

        return topK;
    }
};
  • golang
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • “Yesterday I was clever, so I wanted to change the world. Today I am wise, so I am changing Myself."
  • 昨天的我聪明,想去改变这个世界。今天的我智慧,正在改进自我。
  • 一、描述
  • 二、思路
    • 最迷惑地方 pair (u,v)
      • 熟悉子问题:
        • 描述
          • 测试bug
          • 三、代码
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档