Leetcode1326 Minimum Number of Taps to Open to Water a Garden 题解
原题
链接:https://leetcode.com/problems/minimum-number-of-taps-to-open-to-water-a-garden/
大意:
- 有大小[0,n]大小的花园,每个点上都可以放水龙头(一共可以放n+1个水龙头)
- 给定每个水龙头的浇水的范围(ranges),问能使得整个花园全部浇到水的最少的水龙头的数量。
我的思路
- 一开始联想到了之前做过的一道区间覆盖的问题,觉得应该对区间进行排序。于是有了以下的思路。
- 先对区间的下界进行递增的排序,注意到有的区间下界小于0,有的上界大于n,为方便处理,小于0的置为0,大于n的置为n。
- 在选定一个区间之后,选择下一个的区间的方法是:遍历下界在上一个区间的之间的区间,选择上界的最大的,重复上述过程。(这样就能保证最少,因为要保证全覆盖,必须区间有交集,保证最少,就取最大的上界)
- 若在上述过程中,没有合适的区间选择,那么退出这过程,若上界大于等于n,则成功,否则失败。
AC代码
#include<iostream>
using namespace std;
class interval{
public:
int low;
int high;
interval(int tmpl,int tmph){
low=tmpl;
high=tmph;
}
};
bool cmp(interval a,interval b)
{
return a.low<b.low;
}
class Solution {
public:
int minTaps(int n, vector<int>& ranges) {
vector<interval>tmpv;
for(int i=0;i<ranges.size();i++)
{
int tmpl=i-ranges[i];
int tmph=i+ranges[i];
if(i-ranges[i]<0){tmpl=0;}
if(i+ranges[i]>n){tmph=n;}
tmpv.push_back(interval(tmpl,tmph));
}
sort(tmpv.begin(),tmpv.end(),cmp);
int rel=0;
vector<interval>::iterator it=tmpv.begin();
int lastMax=0;
int lastTmp;
while(it!=tmpv.end())
{
lastTmp=lastMax;
while(it!=tmpv.end()&&it->low<=lastMax){
lastTmp=max(lastTmp,it->high);
it++;
}
if(lastTmp>lastMax){rel++;lastMax=lastTmp;}
else{break;}
}
if(lastMax>=n){return rel;}
return -1;
}
};