LeetCode 632. Smallest Range
阿新 • • 發佈:2018-12-15
題意:給定k個排好序的陣列,求出長度最小的range [l,r]使得每個陣列至少有一個元素出現在range內。
很明顯的一個observation是l,r一定是陣列中的數。如果只有一個數組,用兩個pointer就OK。列舉r,隨著r的增加,l不斷右移保證cover所有的陣列即可。
開始在糾結一維陣列中的r=r+1情況怎麼對應到k個數組中。
對於K個數組,這種case和merge k sorted lists很像。l右移時每次都指向最小的元素,所以可以通過priority queue實現。如果tmp=que.top()是某個陣列k在queue中唯一的的元素,說明l無法再向右移,且是當前的r下最大的l,為了保證cover所有的陣列,需要在que push tmp之後的元素tmp_next,如果r比tmp_next小,則update r。
初始化時把K個數組的第一個元素都push進que中,pointer指向每個陣列的開頭。如果某一個數組k的pointer已經指向末尾,說明l無法再向右移,且r再向右移只會讓區間更大,所以這種情況下可以直接結束。
#include<iostream> #include<stdio.h> #include<cstdio> #include<string> #include<cmath> #include<stdlib.h> #include<algorithm> #include<string.h> #include<cstring> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> #include<stack> using namespace std; //leetcode 632. Smallest Range const int maxn=3510; int T; int N; int M; class CompareDist { public: bool operator()(pair<int,int> n1,pair<int,int> n2) { if(n1.first==n2.first) { return n1.second>n2.second; } return n1.first>n2.first; } }; class Solution { public: int freq[maxn]; int pointer[maxn]; priority_queue<pair<int,int>,vector<pair<int,int>>,CompareDist>que; vector<int> smallestRange(vector<vector<int>>& nums) { int left=nums[0][0]; int right=nums[0][0]; vector<int>range={-100000,100000}; memset(freq,0,sizeof(freq)); memset(pointer,0,sizeof(pointer)); while(!que.empty()) { que.pop(); } for(int i=0;i<nums.size();i++) { pair<int,int>tmp=make_pair(nums[i][pointer[i]],i); pointer[i]++; que.push(tmp); left=min(left,tmp.first); right=max(right,tmp.first); freq[i]++; } while(!que.empty()) { while(true) { pair<int,int>tmp=que.top(); if(freq[tmp.second]>1) { que.pop(); freq[tmp.second]--; // cout<<"pop "<<tmp.first<<endl; } else { left=tmp.first; // cout<<"left "<<left<<" right "<<right<<endl; if(range[1]-range[0]>right-left) { range[0]=left; range[1]=right; } break; } } pair<int,int>tmp=que.top(); if(pointer[tmp.second]!=nums[tmp.second].size()) { que.push(make_pair(nums[tmp.second][pointer[tmp.second]],tmp.second)); right=max(right,nums[tmp.second][pointer[tmp.second]]); // cout<<"push "<<nums[tmp.second][pointer[tmp.second]]<<" from "<<tmp.second<<endl; pointer[tmp.second]++; freq[tmp.second]++; } else { break; } } // cout<<range[0]<<" "<<range[1]<<endl; return range; } }; int main() { // priority_queue<pair<int,int>,vector<pair<int,int>>,CompareDist>que; // for(int i=0;i<10;i++) // { // pair<int,int>tmp=make_pair(2,i); // que.push(tmp); // } // while(!que.empty()) // { // pair<int,int>tmp=que.top(); // que.pop(); // cout<<tmp.first<<" "<<tmp.second<<endl; // } // return 0; freopen("input.txt","r",stdin); cin>>T; for(int ca=1;ca<=T;ca++) { cin>>N; vector<vector<int> >matrix; for(int i=0;i<N;i++) { cin>>M; matrix.push_back(vector<int>()); for(int j=0;j<M;j++) { int tmp; cin>>tmp; matrix[i].push_back(tmp); } } Solution sol; sol.smallestRange(matrix); // cout<<"Case #"<<ca<<": "<<sol.largestRectangleArea(matrix)<<endl; } return 0; }