zoukankan      html  css  js  c++  java
  • 632. Smallest Range

    问题描述:

    You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the klists.

    We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c.

    Example 1:

    Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
    Output: [20,24]
    Explanation: 
    List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
    List 2: [0, 9, 12, 20], 20 is in range [20,24].
    List 3: [5, 18, 22, 30], 22 is in range [20,24].
    

    Note:

    1. The given list may contain duplicates, so ascending order means >= here.
    2. 1 <= k <= 3500
    3. -105 <= value of elements <= 105.
    4. For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.

    解题思路:

    首先我们将所有数组混合到一起,为了标识它原本属于哪个数组,我们用pair来存储,pair.first为数值, pair.second为它来自哪个数组。

    然后我们用sort将其排序。

    排序后可以用滑动窗口来解决这个问题。

    即,找一个窗口两端差最小的窗口,窗口里的值必须每个链表中的至少一个值。

    可以参考 76. Minimum Window Substring

    不过将比较值设为v[i].first - v[l].first。

    同时我们也用一个map来存储k个链表中的值的个数。

    代码:

    class Solution {
    public:
        vector<int> smallestRange(vector<vector<int>>& nums) {
            unordered_map<int, int> m;
            vector<pair<int,int>> v;
            vector<int> ret;
            for(int i = 0; i < nums.size(); i++){
                for(int j = 0; j < nums[i].size(); j++){
                    v.push_back(pair<int,int>(nums[i][j], i));
                }
                m[i] = 1;
            }
            sort(v.begin(), v.end());
            int count = 0;
            int l = 0, len = INT_MAX;
            int k = nums.size();
            for(int i = 0; i < v.size(); i++){
                pair<int, int> p = v[i];
                m[p.second]--;
                if(m[p.second] > -1)
                    count++;
                while(count == k && l <= i){
                    if(len > (v[i].first - v[l].first)){
                        len = v[i].first - v[l].first;
                        ret = {v[l].first, v[i].first};
                    }
                    if(++m[v[l].second] == 1)
                        count--;
                    l++;
                }
            }
            return ret;
        }
    };
  • 相关阅读:
    樊登读书 认知天性
    【笔记】Tapable源码解析图以及webpack怎样实现一个插件plugin
    web前端使用mcg-helper代码生成工具学习笔记
    博客记录
    15ISK 驱动 BIOS等
    蒙特卡洛方法和蒙特卡洛树搜索
    求最大k个数
    求阶乘的位数和后缀0个数
    五分钟看懂一致性哈希算法
    Windows下查看GPU(NVIDIA)使用情况
  • 原文地址:https://www.cnblogs.com/yaoyudadudu/p/9176226.html
Copyright © 2011-2022 走看看