leetcode 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 k lists.

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.
我的解题思路是,将二维数组中的数据放到一维数组中去,一维数组中的元素为pair<int,int>,first代表value实际值,second代表key值,表示其来自于第几个列表。然后用first当谓词sort一维数组,再用动态规划的办法确定最小范围。
动态规划具体如下:维持一个vsCounts数组,和一个visitedCount变量,当第一次visitedCount==nums.size()的时候,表示此时范围内拥有了来自所有列表内的值。记录下此时的minBegin,和minEnd值,后面每次遍历到当前key值等于当前范围第一个位置的key值的时候,将起始值不断前移,缩小最小范围,缩小到无法缩小时,与历史最小范围比较,将其更新。
这样直到遍历allNums完毕,可得到所求结果。
54ms

class Solution {
public:
    vector<int> smallestRange(vector<vector<int>>& nums) {
        vector<pair<int,int>>allNums;//first代表value值,second代表key值。
        for(int i=0;i<nums.size();++i){//将nums放到一维数组中
            for(auto j:nums[i]){
                allNums.push_back({j,i});
            }
        }
        sort(allNums.begin(),allNums.end(),[](auto p1,auto p2){return p1.first<p2.first;});//按元素的value值升序排序。
        int visitedCount=0;//统计已访问列表种类数
        vector<int>vsCounts(nums.size(),0);//记录各列表访问具体次数
        int begin=0;//当前范围起始点,当前范围结束点由下方循环中的k代替。
        int minBegin=0;//最小范围起始点
        int minEnd=allNums.size()-1;//最小范围结束点
        for(int k=0;k<allNums.size();++k){
            int id=allNums[k].second;
            if(vsCounts[id]==0){
                ++visitedCount;
                ++vsCounts[id];
            }else{
                ++vsCounts[id];
                if(id==allNums[begin].second){//如果等于当前范围的起始点,则更新起始点
                    while(vsCounts[allNums[begin].second]>1){
                        --vsCounts[allNums[begin].second];
                        ++begin;
                    }
                }else{//没有更新的话就跳过。
                    continue;
                }
            }
            if(visitedCount==nums.size()){//所有列表都在范围内,更新最小范围。
                if(allNums[k].first-allNums[begin].first<allNums[minEnd].first-allNums[minBegin].first){
                    minBegin=begin;
                    minEnd=k;
                }
            }
        }
        vector<int>res{allNums[minBegin].first,allNums[minEnd].first};
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36946274/article/details/80920318