理论基础
找不到明显的反例可以反驳局部最优推出全局最优就可以试试贪心算法
贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。
不用花心思去研究其规律, 没有思路就立刻看题解。
基本贪心的题目 有两个极端,要不就是特简单,要不就是死活想不出来。
学完贪心之后再去看动态规划,就会了解贪心和动规的区别
455.分发饼干
为了满足更多的小孩,就不要造成饼干尺寸的浪费。
大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。
这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
class Solution {
public int findContentChildren(int[] g, int[] s) {
Arrays.sort(g);//孩子
Arrays.sort(s);//饼干
int index=s.length-1;//饼干的index
int res=0;
//里外如果换了就是外面从大到小控制饼干,如果第一个最大的饼干没给成就会换到第二个最大饼干给最大的小孩,走不了index--的逻辑
for(int i=g.length-1;i>=0;i--){//小孩子从大胃口开始投喂
if(index>=0&&s[index]>=g[i]){//这里用for循环不合适!! 从大到小投喂,如果投喂成功,就进行下一个循环
res++;
index--;//因此要在if控制index不能小于0
}
}
return res;
}
}
376.摆动序列
class Solution {
public int wiggleMaxLength(int[] nums) { //输入数组判断最大子摆动序列 一正一负
if(nums.length==1) return 1;
// if(nums.length==2) return 2;[0,0]不可以
int prediff=0;
int curdiff=0;
//记录结果 默认最右端有一个波动
int res=1;
for(int i=0;i<nums.length-1;i++){
curdiff=nums[i+1]-nums[i];
//必须一正一负之前有平坡也可以所以也可以为0
if((prediff<=0&&curdiff>0)||(prediff>=0&&curdiff<0)){
res++;
prediff=curdiff;
}
}
return res;
}
}
53.最大子序和
只要连续和不是负数就一直往后加
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优
class Solution {
public int maxSubArray(int[] nums) {
if(nums.length==1) return nums[0];
int maxsum=Integer.MIN_VALUE;
int cursum=0;
// int sum=Integer.MIN_VALUE; 不需要
for(int i=0;i<nums.length;i++){
cursum+=nums[i];//如果加上当前的值是一个负值 sum<0会越减越小,则在下方重置sum
maxsum=Math.max(maxsum,cursum);
if(cursum<=0) cursum=0;
}
return maxsum;
}
}