开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!
Leetcode学习之贪心算法(3)
题目来源:
题目描述:已知在一个平面上有一定数量的气球,平面可以看作成一个坐标系,在平面的x轴的不同位置安排弓箭手向y轴方向射箭,弓箭可以向y轴走无穷远;给定气球的宽度为:
,问至少需要多少弓箭手,可以将气球全部打爆?
思路:
步骤:
测试代码:
#include <algorithm> #include <vector> using namespace std; bool cmp(const pair<int, int>&a, const pair<int, int>&b) { return a.first < b.first;//无需考虑左端点相同时的排序 } class Solution { public: int findMinArrowShots(vector<pair<int, int>>& points) { if (points.size() == 0) { return 0;//传入的数据可能为空,直接返回0 } sort(points.begin(), points.end(), cmp);//对气球按照左端点从小到大进行排序 int shoot_num = 1; int shoot_begin = points[0].first;//初始化弓箭手数量为1 int shoot_end = points[0].second;//初始化射击区间,即为第一个气球的两端点 for (int i = 1; i < points.size(); i++) { if (points[i].first < shoot_end) { shoot_begin = points[i].first; if (shoot_end > points[i].second) { shoot_end = points[i].second; } } else { shoot_num++; shoot_begin = points[i].first;//再保证气球呗射穿的情况下,射击区间不再更新,增加一个射击区间 shoot_end = points[i].second; } } return shoot_num; } }; int main() { vector<pair<int, int>> points; points.push_back(make_pair(10, 16)); points.push_back(make_pair(2, 8)); points.push_back(make_pair(1, 6)); points.push_back(make_pair(7, 12)); Solution solve; printf("%d\n", solve.findMinArrowShots(points)); system("pause"); return 0; }
效果图:
题目来源:
题目描述:已知一条公路上,有一个起点与一个终点,这之间有
个加油站;已知从这
个加油站到终点的距离
与各个加油站可以加油的量
,起点位置至终点的距离
与起始时刻油箱中的汽油量
;假设使用1个单位的汽油即走了1个单位的距离,油箱中没有上限,最少加几次油,可以从起点开至终点?如果无法到达终点,返回-1。
分析:
思路:
测试代码:
#include <vector> #include <algorithm> #include <queue> using namespace std; bool cmp(const pair<int, int> &a, const pair<int, int> &b) { return a.first > b.first; } int get_minimum_stop(int L, int P, vector<pair<int, int>> &stop) {//L为起点到终点的距离,P为起点初始的汽油量,pair<该加油站到终点的距离、加油站汽油量> priority_queue<int> Q;//存储油量的最大堆 int result = 0;//记录加过几次油的变量 stop.push_back(make_pair(0, 0));//将终点作为一个停靠点,添加至stop数组。最后一个点 sort(stop.begin(),stop.end(), cmp);//将以停靠点至终点的距离从大到小进行排序,因为题目中的顺序是乱给的 for (int i = 0; i < stop.size(); i++) {//遍历各个停靠点 int dis = L - stop[i].first;//当前要走的距离:即为当前距离距终点的距离L减去下一个停靠点至终点的距离 while ( dis > P && !Q.empty()) { P += Q.top();//加油 Q.pop(); result++; } if (Q.empty() && P < dis) { return -1; } P = P - dis; L = stop[i].first;//停靠点至终点的距离 Q.push(stop[i].second);//更新L为当前停靠点至终点距离 }//将当前停靠点的汽油量添加至最大堆 return result; } int main() { vector<pair<int, int>>stop; int N=4, L, P, distance, fuel; for (int i = 0; i < N; i++) { scanf("%d %d", &distance, &fuel); stop.push_back(make_pair(distance, fuel)); } scanf("%d %d", &L, &P); printf("%d\n", get_minimum_stop(L, P, stop)); system("pause"); return 0; }