代码随想录算法训练营第23天|455.分发饼干、376. 摆动序列、53. 最大子数组和
LeetCode455
2025-02-23 22:15:20 星期日
题目描述:力扣455
文档讲解:代码随想录(programmercarl)455.分发饼干
视频讲解:《代码随想录》算法视频公开课:贪心算法,你想先喂哪个小孩?| LeetCode:455.分发饼干
代码随想录视频内容简记
贪心算法就是通过求得局部最优,来推得一个全局最优
梳理
-
首先对g胃口进行排序,s饼干值进行排序
-
要做的就是让饼干逐个匹配孩子的胃口值,这是局部最优。之后尽量满足每一个孩子的胃口来求得全局最优
大致代码内容
-
对胃口值进行遍历
for (int i = g.size() - 1; i >= 0; i--)
-
之后对饼干值进行遍历,
if (index >= 0 && s[index] >= s[i]) index--; result++;
-
这里有一个小细节,那么for循环内就一定是g胃口值,能不能是s饼干值呢?答案是可以的,这是在k哥视频中讲到的从小的饼干开始喂和从大的饼干开始喂联想了一下。
-
首先,如果for循环中是g胃口值,那么就只能从大饼干开始喂。
g[7,8,9,10],s[5,6,7,8]如果从大饼干开始喂,那么就是从后向前遍历,8<10, 8<9,8等于8,这时result+1,7==7,result再+1,能喂两个孩子,没有问题。
但是从小饼干开始喂,也就是从前向后遍历,5<7,5<8,5<9,5<10,那么result就等于0
-
如果for循环中是s饼干值,那么就只能从小饼干开始喂。
这个也是同理的
这个的关键就是if条件如果一直得不到满足,那么index的索引就不会发生变化。
-
LeetCode测试
总结一下,也就是只能是大胃口先得到大饼干,或者小饼干先喂饱小胃口。
for中是g胃口值,从大饼干开始喂
点击查看代码
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int index = s.size() - 1;
int result = 0;
for (int i = g.size() - 1; i >= 0; i--) {
if (index >= 0 && s[index] >= g[i]) {
index--;
result++;
}
}
return result;
}
};
for中是s饼干值,从小饼干开始喂
点击查看代码
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int index = 0;
int result = 0;
for (int i = 0; i < s.size(); i++) {
if (index < g.size() && s[i] >= g[index]) {
result++;
index++;
}
}
return result;
}
};
LeetCode376
题目描述:力扣376
文档讲解:代码随想录(programmercarl)376. 摆动序列
视频讲解:《代码随想录》算法视频公开课:贪心算法,寻找摆动有细节!| LeetCode:376.摆动序列
代码随想录视频内容简记
这个题很难想,需要考虑的情况很多。这个题的局部最优是消除每个顶峰中间的元素,全局最优就是找到一个最长的摆动子序列
梳理
- 上下坡有平坡
这种就是需要定义一个prediff和一个curdiff来,如果prediff >= 0 && curdiff < 0
或者prediff <= 0 && curdiff > 0
,那么就对结果 + 1

- 首尾元素
这种就是如果只有两个元素,[2, 5]
,他的摆动序列就只是2, 但是按照prediff和curdiff最少需要3个元素,那么我们就只能"虚拟"一个头部元素,假设他的prediff=0就不会影响了。

- 单调有平坡
这种情况k哥是在最后讲的,这里需要额外注意一个prediff的更新时间

prediff只有在每次发生波动的情况下才会更新,如果他一直是一个单调的坡,那么就不会更新,所以这个prediff = curdiff
一定要写在if的条件判断里面
if (prediff >= 0 && curdiff < 0 || prediff <= 0 && curdiff > 0) {
result++;
prediff = curdiff;
}
LeetCode测试
点击查看代码
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() == 1) return 1;
int prediff = 0;
int curdiff;
int result = 1;
for (int i = 0; i < nums.size() - 1; i++) {
curdiff = nums[i + 1] - nums[i];
if (prediff >= 0 && curdiff < 0 || prediff <= 0 && curdiff > 0) {
result++;
prediff = curdiff;
}
}
return result;
}
};
LeetCode53
题目描述:力扣53
文档讲解:代码随想录(programmercarl)53. 最大子数组和
视频讲解:《代码随想录》算法视频公开课:贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和
代码随想录视频内容简记
这道题的贪心策略就是如果一个数让当前的连续子序和变成了负数,那么他就只会让后面的子序列就立马抛弃这个数,从下一个数开始重新计数。这里的实现就是给count重新赋值为0,那么相当于跳过这个元素从后面的元素重新开始记和。
举个例子

但是如果加一个数,让当前变成正数,他就一定是最大子序列的开始位置吗?这也不一定,如果涉及到了子序列的开始位置和终止位置,情况又会复杂不少。

卡哥视频里记录的这个序列,[4,3,5,6]是最大子序列,如果要是记录他的起始和终止,可能得用双指针来解
LeetCode测试
点击查看代码
class Solution {
public:
int maxSubArray(vector<int>& nums) {
if (nums.size() == 1) return nums[0];
int result = INT_MIN;
int count = 0;
for (int i = 0; i < nums.size(); i++) {
count += nums[i];
if (count > result) result = count;
if (count < 0) count = 0;
}
return result;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端