贪心算法思考
想清楚局部最优,想清楚全局最优,感觉局部最优是可以推出全局最优,并想不出反例,那么就试一试贪心算法
例题:
455. 分发饼干
方法:小饼干给胃口小的
先排序两个数组,遍历饼干数组,用index表示小孩子的下标,如果饼干能喂饱小孩子,那么index移动,喂不饱就不移动(index),当遍历完饼干index表示的就是能喂饱多少个孩子
cpp
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
if (s.size() == 0) return 0;
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int index = 0;
for (int i = 0; i < s.size(); i++) {
if (index < g.size() && g[index] <= s[i]) index++;
}
return index;
}
};
376. 摆动序列
方法:删除单调坡度上的节点
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
cpp
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0, preDiff = 0;
int ret = 1;
for (int i = 0; i < nums.size() - 1; i++) {
curDiff = nums[i + 1] - nums[i];
if ((preDiff >= 0 && curDiff < 0) || (preDiff <= 0 && curDiff > 0)) {
ret++;
preDiff = curDiff;
}
}
return ret;
}
};
也可以用动态规划做这个题,在此不提
53. 最大子数组和
方法:抛弃连续和为负数的情况
局部最优:当前"连续和"为负数的时候立刻放弃,从下一个元素重新计算"连续和",因为负数加上下一个元素 "连续和"只会越来越小。全局最优:选取最大"连续和"
cpp
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int ret = INT_MIN;
int count = 0;
for (int i = 0; i < nums.size(); i++) {
count += nums[i];
if (count > ret) ret = count;
if (count < 0) count = 0;
}
return ret;
}
};
也可以用动态规划做这个题,在此不提