刷题第31天 | 贪心算法理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

本文探讨贪心算法的基础理论,并通过LeetCode的三道题目455. Assign Cookies、376. Wiggle Subsequence和53. Maximum Subarray进行实战解析。贪心策略通过局部最优解逐步构造全局最优解,例如在分发饼干问题中,通过排序和双指针策略找到最佳匹配,而在摆动序列和最大子序和问题中,同样利用双指针和局部最优选择来寻找最优点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贪心算法理论基础

链接:代码随想录贪心算法理论基础

思路

贪心算法说到底就是一句话,通过找到每一阶段的局部最优,来达到全局最优的效果。
大致思路为:

  1. 将问题分解为若干个子问题
  2. 找出适合的贪心策略
  3. 求解每一个子问题的最优解
  4. 将局部最优解堆叠成全局最优解

455. Assign Cookies

题目链接:455. Assign Cookies
思路链接:代码随想录贪心算法-分发饼干

思路

在代码随想录中的思路是从右到左(从大到小)遍历,而我给的解法是从左到右(从小到大)遍历,但其实是一样的。
在这里插入图片描述

代码随想录的思路是将最大的饼干先喂给最大能够满足的小孩,充分利用饼干尺寸喂饱一个,以达到喂饱所有小孩的全局最优效果;我的思路是将最小的饼干先喂给最小能够满足的小孩,充分利用饼干尺寸喂饱一个,以达到喂饱所有小孩的目的。
做法是将两个数组排序,然后利用双指针,在两个数组上分别定义一个指针,同时开始遍历,如果当前饼干能够满足,那么两个指针同时更新,否则饼干数组指针更新。

Code

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int index1 = 0;
        int index2 = 0;
        while (index1 != g.length && index2 != s.length) {
            if (s[index2] >= g[index1]) {
                index1++;
                index2++;
            } else {
                index2++;
            }
        }
        return index1;
    }
}

376. Wiggle Subsequence

题目链接:376. Wiggle Subsequence
思路链接:代码随想录贪心算法-摆动序列

思路

不要陷入模拟删除元素的思路中。将数组元素值抽象成山峰图。
在这里插入图片描述
通过使序列删除元素后,达到局部峰值的最大值就可以得到答案。
局部最优:通过删除单调坡度上的节点来得到局部峰值
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列

利用双指针,记录得到当前元素与下一元素之差以及上一元素与当前元素之差。在遍历数组时,如果两个指针的值正负号相异,那么就代表找到了一个局部峰值,更新result。

Code

class Solution {
    public int wiggleMaxLength(int[] nums) {
        if (nums.length <= 1) {
            return nums.length;
        }
        // 通过当前组之差与前一组之差比较来判断是否是峰值
        int currDiff = 0;
        int preDiff = 0;
        int result = 1;
        for (int i = 0; i < nums.length - 1; i++) {
            currDiff = nums[i + 1] - nums[i];
            if (currDiff > 0 && preDiff <= 0 || currDiff < 0 && preDiff >= 0) {
                result++;
                preDiff = currDiff;
            }
        }
        return result;
    }
}

53. Maximum Subarray

题目链接:53. Maximum Subarray
思路链接:代码随想录贪心算法-最大子序和

思路

暴力解法:两个循环。第一个循环设定起始位置,第二个循环的起始位置是第一个循环遍历到的元素。
贪心算法:
在这里插入图片描述
红色的起始位置就是贪心每次取count为正数的时候,开始一个区间的统计。

局部最优:记录最大的连续和
全局最优:最大子序和
预先定义result(整数最小值)和count(0)遍历数组,遍历数组,计算count,如果count大于result,更新result,如果count出现负数,那么重置count为0。
这道题的思路比较难想。

Code

class Solution {
    public int maxSubArray(int[] nums) {
        int result = Integer.MIN_VALUE;
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            count += nums[i];
            if (count > result) {
                result = count;
            }
            if (count <= 0) {
                count = 0;
            }
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值