什么是贪心
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
贪心一般解题步骤
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。
LeetCode刷题
LeetCode455:分发饼干
思路:为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。
想清楚局部最优,想清楚全局最优,感觉局部最优是可以推出全局最优,并想不出反例,那么就试一试贪心。
var findContentChildren = function(g, s) {
g = g.sort((a, b) => a - b);
s = s.sort((a, b) => a - b);
let res = 0;
let index = s.length - 1;
for (let i = g.length - 1; i>= 0; i--) {
if (index >= 0 && s[index] >= g[i]) {
res ++;
index --;
}
}
return res;
};
LeetCode376:摆动序列
本题要求通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。举例说明:
局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。局部最优推出全局最优,并举不出反例,那么试试贪心!实际操作上,其实连删除的操作都不用做,因为题目要求的是最长摆动子序列的长度,所以只需要统计数组的峰值数量就可以了(相当于是删除单一坡度上的节点,然后统计长度)。这就是贪心所贪的地方,让峰值尽可能的保持峰值,然后删除单一坡度上的节点。
var wiggleMaxLength = function(nums) {
if (nums.length <= 1) {
return nums.length;
}
let result = 1;
let preDiff = 0;
let curDiff = 0;
for (let i = 0; i < nums.length - 1; i++) {
curDiff = nums[i + 1] - nums[i];
if ((curDiff > 0 && preDiff <= 0) || (curDiff < 0 && preDiff >= 0)) {
result ++;
preDiff = curDiff;
}
}
return result;
};
<扩展>动态规划
var wiggleMaxLength = function(nums) {
if (nums.length === 1) return 1;
// 考虑前i个数,当第i个值作为峰谷时的情况(则第i-1是峰顶)
let down = 1;
// 考虑前i个数,当第i个值作为峰顶时的情况(则第i-1是峰谷)
let up = 1;
for (let i = 1; i < nums.length; i++) {
if (nums[i] < nums[i - 1]) {
down = Math.max(up + 1, down);
}
if (nums[i] > nums[i - 1]) {
up = Math.max(down + 1, up)
}
}
return Math.max(down, up);
};
LeetCode53:最大子序和
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。全局最优:选取最大“连续和”。局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
var maxSubArray = function(nums) {
let result = -Infinity
let count = 0
for(let i = 0; i < nums.length; i++) {
count += nums[i]
if(count > result) {
result = count
}
if(count < 0) {
count = 0
}
}
return result
};
<扩展>动态规划 代补上