day27

day27的任务是贪心算法,这个没有模板可以套,不像二叉树和回溯。个人觉得确实想不到就是想不到,先练练试试吧。


1.贪心的理论基础:代码随想录

带着问题看:

贪心是什么?从局部最优解找全局最优解的过程。

贪心可以解决什么问题?

贪心和动态规划的区别。


2.分发饼干:代码随想录

力扣链接:. - 力扣(LeetCode)

其实就是排个序然后保证大份饼干尽量喂给大胃口。但是注意随想录的两种解法,一个是遍历大胃口,一个是遍历饼干,区别一下谁用for,谁用if,为什么?注意细节。

class Solution {
    // 思路1:优先考虑饼干,小饼干先喂饱小胃口
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int start = 0;
        int count = 0;
        for (int i = 0; i < s.length && start < g.length; i++) {
            if (s[i] >= g[start]) {
                start++;
                count++;
            }
        }
        return count;
    }
}

class Solution {
    // 思路2:优先考虑胃口,先喂饱大胃口
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int count = 0;
        int start = s.length - 1;
        // 遍历胃口
        for (int index = g.length - 1; index >= 0; index--) {
            if(start >= 0 && g[index] <= s[start]) {
                start--;
                count++;
            }
        }
        return count;
    }
}

3.摆动序列:代码随想录

力扣链接:. - 力扣(LeetCode)

脑子模拟一下也很容易出过程,只要去掉中间不符合的点,剩下的都是结果,注意可以用计数器,而不用真正移除元素。

随想录的解题思路,大概分为:默认最右为一个摆动元素,数组可能的情况是什么,分为三类,上下坡中有平坡,数组首尾怎么算(包含长度小于2的情况),单调坡中有平坡,其中单调坡中有平坡比较复杂,注意解题代码中if代码块中的语句,品味一下preDiff = curDiff放在if里和if外面有什么区别。

代码如下:

/**
 * 摆动序列
 *
 * https://leetcode.cn/problems/wiggle-subsequence/
 */
public class _27_2WobbleSequence {
    public static int wiggleMaxLength(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }
        int result = 1;
        int preDiff = 0;
        int curDiff = 0;

        for (int i = 1; i < nums.length; i++) {
            //得到当前差值
            curDiff = nums[i] - nums[i - 1];
            //如果当前差值和上一个差值为一正一负
            //等于0的情况表示初始时的preDiff
            if ((preDiff >= 0 && curDiff < 0) || (preDiff <= 0 && curDiff > 0)) {
                result++;
                preDiff = curDiff;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] nums = {1, 17, 5, 10, 13, 15, 10, 5, 16, 8};
        System.out.println(wiggleMaxLength(nums));
    }
}

4.最大子序和:代码随想录

力扣链接:. - 力扣(LeetCode)

贪心的应用就在于多吃几个元素,直到吃掉当前元素后,局部和小于等于0了,从下一个位置开始继续找最大的子序和。

/**
 * 最大子序和
 *
 * https://leetcode.cn/problems/maximum-subarray/
 */
public class _27_3MaxSuborderSum {
    public static int maxSubArray(int[] nums) {
        if (nums.length == 1){
            return nums[0];
        }

        int result = Integer.MIN_VALUE;     //全局最优解
        int count = 0;      //局部最优解
        for (int i = 0;i<nums.length;i++){
            count+=nums[i];
            result = Math.max(result, count);       //比较两个最优解的大小
            if (count<=0){
                count=0;    //如果此时已经小于0了,那么就没必要将这个继续加了,从下一个重新加
            }
        }
        return result;
    }
    public static void main(String[] args) {
        int[] nums = {-2,1,-3,4,-1,2,1,-5,4};
        System.out.println(maxSubArray(nums));
    }
}

上面的题还有动态规划的版本,个人看不懂,上学时候数学推导都不太会别说用代码写了。加油吧,这次不管咋都得试试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值