本文通过leedcode为蓝桥杯省赛做准备
贪心算法:保证每次操作都是局部最优的,从而使最后得到的结果是全局最优的
例题:
1.有一群孩子和一堆饼干,每个孩子有一个饥饿度,每个饼干都有一个大小。每个孩子只能吃最多一个饼干,且只有饼干的大小大于孩子的饥饿度时,这个孩子才能吃饱。求解最多有多少孩子可以吃饱。
贪心策略:给剩余孩子里最小饥饿度的孩子分配最小的能饱腹的饼干。
int findContentChildren(vector<int>& children, vector<int>& cookies) {
sort(children.begin(), children.end());
sort(cookies.begin(), cookies.end());
int child = 0, cookie = 0;
while (child < children.size() && cookie < cookies.size()) {
if (children[child] <= cookies[cookie]) ++child;
++cookie;
}
return child;
}
2.一群孩子站成一排,每一个孩子有自己的评分。现在需要给这些孩子发糖果,规则是如果一个孩子的评分比自己身旁的一个孩子要高,那么这个孩子就必须得到比身旁孩子更多的糖果;所有孩子至少要有一个糖果。求解最少需要多少个糖果。
贪心策略:在每次遍历中,只考虑并更新相邻一侧的大小关系。
int candy(vector<int>& ratings) {
int size = ratings.size();
if (size < 2) { return size; }
vector<int> num(size, 1);//把所有孩子糖果初始化为1
for (int i = 1; i < size; ++i) {
if (ratings[i] > ratings[i-1]) {//往右遍历一遍更新糖果值,这是只考虑右侧大于左侧
num[i] = num[i-1] + 1;
}
}
for (int i = size - 1; i > 0; --i) {
if (ratings[i] < ratings[i-1]) {//往左遍历一遍更新糖果值
num[i-1] = max(num[i-1], num[i] + 1);//进行一下比较
}
}
return accumulate(num.begin(), num.end(), 0); // std::accumulate 求和,第三个参数是累加的初值
}
3.给定多个区间,计算让这些区间互不重叠所需要移除区间的最少个数。起止相连不算重叠。
选择的区间结尾越小,余留给其它区间的空间 就越大,就越能保留更多的区间。因此,我们采取的贪心策略:优先保留结尾小且不相交的区间
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) return 0;
int n = intervals.size();
sort(intervals.begin(), intervals.end(), [](vector<int> a, vector<int> b) { return a[1] < b[1]; });//这个sort是按区间尾元素值进行递增排序
int total = 0, prev = intervals[0][1];
for (int i = 1; i < n; ++i) {
if (intervals[i][0] < prev) ++total;
else prev = intervals[i][1];
}
return total;
}
4.假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
扫描二维码关注公众号,回复:
13201760 查看本文章
![](/qrcode.jpg)
考虑花坛边界的特殊情况
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int ans = 0;
for (int i = 0; i < flowerbed.length; i++) {//判断当前位置能否种花//能种 的情况
if (flowerbed[i] == 0 && (i + 1 == flowerbed.length || flowerbed[i + 1] == 0) && (i == 0|| flowerbed[i - 1] == 0)) {
flowerbed[i] = 1;
ans++;}
}
return ans >= n;
}
}