解法一:贪心
思路:每次选一个区间,区间右端可以覆盖当前需要覆盖的最右端,同时该区间能覆盖的最左侧点索引最小。
代码
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
static bool cmp(vector<int>& pre, vector<int>& next){
return pre[1]<next[1] || (pre[1]==next[1] && pre[0]>next[0]);
}
int solution(int n, vector<vector<int> > intervals){
if(n == 0){
return 0;
}
int len = intervals.size();
if(len == 0 || intervals[len-1][1] < n){
return -1;
}
int left = intervals[len-1][0];
int index = len-1;
while(index>=0){
if(intervals[index][1] >= n){
if(intervals[index][0]<left){
left = intervals[index][0];
}
index--;
}else{
break;
}
}
vector<vector<int> > nextIntervals(intervals.begin(), intervals.begin() + index +1);
int nextValue = solution(left, nextIntervals);
if(nextValue == -1){
return -1;
}
return nextValue+1;
}
int minTaps(int n, vector<int>& ranges) {
vector<vector<int> > intervals;
vector<int>::iterator iter = ranges.begin();
while (iter != ranges.end())
{
if(*iter !=0){
vector<int> internal(2, 0);
int r= *iter;
int center = iter-ranges.begin();
internal[0] = max(center-r, 0);
internal[1] = min(center+r, n);
intervals.push_back(internal);
}
iter++;
}
sort(intervals.begin(), intervals.end(), cmp);
return solution(n, intervals);
}
int main(){
int arr[] = {1,0,4,0,4,1,4,3,1,1,1,2,1,4,0,3,0,3,0,3,0,5,3,0,0,1,2,1,2,4,3,0,1,0,5,2};
int n =35;
vector<int> test(arr, arr+sizeof(arr)/sizeof(int));
cout<< minTaps(n, test) <<endl;
}
解法二:有点像投票:每个需要被灌溉的点,选取一个水龙头,该水龙头可以灌溉到该点,同时是所以可以灌溉到该点的水龙头中,右侧能覆盖到的点索引最大的水龙头
代码
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int minTaps(int n, vector<int>& ranges){
vector<int> covered(n+1, 0);
for(int i=0;i<=n;i++){
if(ranges[i] == 0){
continue;
}
int l=max(0, i-ranges[i]);
int r=min(n, i+ranges[i]);
for(int j=l;j<=r;j++){
covered[j] = max(covered[j], r);
}
}
int index = 0;
int step = 0;
while(index<=n){
if(index == n){
break;
}
if(covered[index] == 0 || (covered[index]<n && covered[covered[index]] == covered[index])){
return -1;
}
index = covered[index];
step++;
}
return step;
}
int main(){
int arr[] = {1,0,4,0,4,1,4,3,1,1,1,2,1,4,0,3,0,3,0,3,0,5,3,0,0,1,2,1,2,4,3,0,1,0,5,2};
int n =35;
vector<int> test(arr, arr+sizeof(arr)/sizeof(int));
cout<< minTaps(n, test) <<endl;
}