今天学到了贪心算法,贪心算法得本质就是从局部最优解导致全局最优,其中序列问题值得二刷。
1.力扣455(分发饼干)
贪心算法要找到贪心得点在哪里,这里是想让饼干得到充分利用,让大饼干满足胃口大得小孩,所以我们局部最优也就出来了,首先让两个数组从尾部遍历,让饼干和小孩相匹配,若碰到能满足得就给他,然后将饼干和小孩向下移动,直至for循环结束。
整体代码:
public int findContentChildren(int[] g, int[] s) {
//保证数组有序
Arrays.sort(g);
Arrays.sort(s);
//记录满足的小孩数
int count = 0;
//规定饼干数组从尾遍历
int index = s.length-1;
//从尾遍历小孩数组
for(int i=g.length-1;i>=0;i--){
if(index>=0&&s[index]>=g[i]){//满足就向后移动
index--;
count++;
}
}
return count;
}
2.力扣376(摆动序列)
本题的局部最优就是去掉单调的峰值,整体最优就是整体有最多的峰值数量(包括峰顶和峰谷),在这里默认count的初始值为1,而在判断是pre等于0时也满足,则就记录了左右的两端的峰值。而我们判断前后是否为峰值,我们利用了pre和cur,分别来记录上一个查值,在每次循环时我们判断是否为一正一负,若满足则产生了峰值。下面时整体代码:
public int wiggleMaxLength(int[] nums) {
//前一段差值
int pre = 0;
/当前差值
int cur = 0;
//峰值的数量
int count = 1;
//遍历数组
for(int i=0;i<nums.length-1;i++){
cur = nums[i+1]-nums[i];
//一正一负
if((cur>0&&pre<=0)||(cur<0&&pre>=0)){
count++;
pre = cur;
}
}
return count;
}
3.力扣53(最大子数组和)
本题的局部最优是局部的最大连续和最大,从而找出全局最优。从代码角度上来讲:遍历nums,从头开始用count累积,如果count一旦加上nums[i]变为负数,那么就应该从nums[i+1]开始从0累积count了,因为已经变为负数的count,只会拖累总和。整体代码:
public int maxSubArray(int[] nums) {
//赋值为最小,用来记录整体最大
int maxSum = Integer.MIN_VALUE;
//记录局部最大
int sum = 0;
//循环遍历数组
for(int i=0;i<nums.length;i++){
sum+=nums[i];
if(sum>maxSum){
maxSum=sum;
}
if(sum<0){//为负直接重新记录
sum=0;
}
}
return maxSum;
}