1. 关于贪心
- 问题分析:梳理与理解问题特性,包括状态定义、优化目标和约束条件等 待施工
- 确定贪心策略:把问题拆分成子问题,在每个子问题中找到局部最优解(贪心选择)。
- 正确性证明:证明问题具有贪心选择性质和最优子结构(局部最优能够导向全局最优)
- 反证法:假设用除了最优解以外的方法来解决问题,然后与和最优解解决相比较,发现其效果劣于最优解,说明最优解成立
贪心的应用场景
待施工
2. 例题
lc455 分发饼干
易错点
- 如果从小到大遍历小孩胃口,那对i他们的饼干挑选也从小到大,反之亦然,不能一正一反,想当然觉得<小孩应该从大到小遍历,而饼干应该抠着给每个人最小的那块>,注意目标是让尽可能多的小孩吃到饼干,而不是抠
- 还是在用嵌套循环,没有考虑到遍历一数组的时候针对另一个数组需要一个动态的游标
在startIndex<s.length和startIndex<=s.length-1都可以写的时候,优先写前者,因为后者会涉及到s.length=0导致出错的问题 - 在if里,应该先判断if(startIndex<g.length),再判断if(startIndex<g.length),如果已经超出,则g[startIndex]就会报错,不能反过来写
思路
思路:分解为:对每个孩子分饼干找最优解
思路1:以饼干为基础,优先把最小饼干分给最小胃口小孩,往上走——遍历饼干
思路2:以胃口为基础,优先把最大饼干分给最大胃口小孩,往下走——遍历胃口
代码实现
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);
Arrays.sort(s);
int num=0;
int startIndex = 0;
for(int i=0;i<s.length;i++){
if(startIndex<g.length && s[i]>=g[startIndex]){
//注意,这里是用饼干去找胃口,先遍历小的饼干看哪块合适
num++;
startIndex++;
}
}
return num;
}
}
…
lc376 摆动序列
易错点
审题不清。不是只找连续存在摆动序列的数组,而是可以跨过几个元素建立摆动序列。所以只要找打num[next]能够和num[cur]的差值diff与prevdiff正负相反就可以
思路
- 一个准摆动序列点上,diff必须!=0 且与prevdiff符号相反
- 但是它的prevdiff可能会=0,也正是因为=0,才需要去找新的diff,故在比较差值的时候,需要给prevdiff加上=0的条件
代码实现
class Solution {
public int wiggleMaxLength(int[] nums) {
if (nums.length <= 1) {
return nums.length;
}
int max = 1; // 最小长度为1
int prevDiff = nums[1] - nums[0];
if (prevDiff != 0) {
max = 2;
}
for (int i = 2; i < nums.length; i++) {
int diff = nums[i] - nums[i - 1];
if ((diff > 0 && prevDiff <= 0) || (diff < 0 && prevDiff >= 0)) {
max++;
prevDiff = diff;
} else if (diff != 0) {
prevDiff = diff; // 开始新的摆动序列
}
}
return max;
}
}
…
lc53 最大子数和
我琢磨着这也不是贪心阿
与376不同,这里需要连续数组
思路
两个问题:
1.要不要在当前连续和 cursum 中继续加入 nums[i]。
2.要不要以 nums[i] 为起点,重新开始计算连续和。
注意:是以nums[i]为基准,比较它和 nums[i] + currentSum 的值,来选择:是继续cursum+=nums[i] or 还是nums[i]自立门户
代码实现
//动态规划
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length==1){
return nums[0];
}
int cursum= nums[0];
int maxsum = nums[0];
for(int i=1;i<nums.length;i++){
cursum = Math.max(cursum+nums[i],nums[i]); //比较的是nums[i]和+cursum的大小,而不是反过来!
maxsum = Math.max(cursum,maxsum);
}
return maxsum;
}
}