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
.
题解:本题需要用到最小堆维持一列的数组元素。题意本质就是找一个数组每个数分别来自每一行中的某一个,使得这个数组最大数和最小数差最小,暴力遍历需要每次都要遍历来找最大数和最小数,由于题目每行数组都是有序的,所以可以维持一个最小堆从每行第一个数开始直到遍历完整个表,遍历过程更新差。注意这里重写优先队列cmp方法时只能用指针,不能传入外部参数,如下代码:
vector<int> smallestRange(vector<vector<int> >& nums) {
struct cmp{
bool operator()(pair<int,int> p1,pair<int,int> p2){
return nums[p1.second][p1.first]>nums[p2.second][p1.first];
}
};
priority_queue<pair<int,int>,vector<pair<int,int> >,cmp> pq;
int lo=INT_MAX,hi=INT_MIN;
for(int i=0;i<nums.size();i++)
{
lo=min(lo,nums[i][0]);
hi=max(hi,nums[i][0]);
pq.push({0,i});
}
vector<int> ans={lo,hi};
while(true)
{
auto p=pq.top();
p.first++;
pq.pop();
if(p.first==nums[p.second].size())break;
pq.push(p);
lo=nums[pq.top().second][pq.top().first];
hi=max(hi,nums[p.second][p.first]);
if(hi-lo<ans[1]-ans[0])ans={lo,hi};
}
return ans;
}
会产生:
use of parameter from containing function
vector<int> smallestRange(vector<vector<int>>& nums) {
typedef vector<int>::iterator vi;
struct comp {
bool operator()(pair<vi, vi> p1, pair<vi, vi> p2) {
return *p1.first > *p2.first;
}
};
int lo = INT_MAX, hi = INT_MIN;
priority_queue<pair<vi, vi>, vector<pair<vi, vi>>, comp> pq;
for (auto &row : nums) {
lo = min(lo, row[0]);
hi = max(hi, row[0]);
pq.push({row.begin(), row.end()});
}
vector<int> ans = {lo, hi};
while (true) {
auto p = pq.top();
pq.pop();
++p.first;
if (p.first == p.second)
break;
pq.push(p);
lo = *pq.top().first;
hi = max(hi, *p.first);
if (hi - lo < ans[1] - ans[0])
ans = {lo, hi};
}
return ans;
}