理论基础:代码随想录
455.分发饼干
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//455 分发饼干
int findContentChildren(vector<int>& g, vector<int>& s) {
//step1 对胃口和饼干排序
sort(g.begin(), g.end());
sort(s.begin(), s.end());
//step2 从最小的胃口开始满足
int index = 0;
int result = 0;
for (int i = 0; i < s.size(); i++) {
while (index < g.size() && s[i] >= g[index]) {
index++;
result++;
//退出while循环,防止s[i]被重复使用
break;
}
}
return result;
}
2.本题小节
思考:贪心算法没有具体规律可言,针对需要解决的问题进行拆分,找到局部最优解来组合成全局最优解。根据本题的题意,从满足最小胃口孩子开始。
基本思路:要从最小胃口孩子开始满足起,首先对胃口以及饼干进行排序,然后遍历饼干,满足孩子胃口后对result++,并换胃口。最后返回统计的结果。
376. 摆动序列
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//376.摆动序列
int wiggleMaxLength(vector<int>& nums) {
//nums数组较小的情况
if (nums.size() <= 1) {
return nums.size();
}
int prediff = 0;
int curdiff = 0;
//最后一个默认为摆动
int result = 1;
for (int i = 0; i < nums.size() - 1; i++) {
//计算当前坡度
curdiff = nums[i + 1] - nums[i];
//包含两种情况
//情况一:常规情况,无平坡
//情况二:有平坡,但是只取平坡最右边的节点,其他的删掉,
//这里第一个节点也适用
//如果实时更新prediff,情况二会将单调有平坡的情况也算入
//因此prediff的更新应该在出现摆动后,这样prediff就不会被
//更新为0,不会在单调平坡时被错误计算
if (prediff >= 0 && curdiff < 0 ||
prediff <= 0 && curdiff > 0) {
result++;
//情况三:摆动后更新,避免单调平坡算摆动的情况
prediff = curdiff;
}
}
return result;
}
2.本题小节
思考:本题要想一次做好并不简单,本题不要陷入误区,由于只需要统计摆动的次数,因此不需要删掉元素。把各种情况进去。
基本思路:本题的核心思路是对数组进行遍历,通过判断prediff与curdiff的关系来决定是否为摆动。情况一,无平坡,prediff*curdiff<0;情况二,有平坡,但是取最右侧位置,此时prediff=0,curdiff != 0,但是这种情况会把单调平坡包含进去,因此情况三,单调平坡,是将prediff的值放在检测到摆动时再更新的,这样会直接保存prediff的坡度直接到下一个相反的坡度,就不怕平破了,包括情况二,因此我推测情况二是为了给第一个数来做判断用得,因为第一个数的prediff我们假设为0,因此对应了第二种情况,同时result初始为1,因为默认最后一个数为偏摆,因此遍历时把最后一个数直接pass了。
53. 最大子序和
题目链接/文章讲解/视频讲解:代码随想录
1.代码展示
//53最大子数组和
int maxSubArray(vector<int>& nums) {
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;
}
2.本题小节
思考:本题使用贪心算法,依然是求局部最优,使得整体最优。在累加计算时,累加为负数,那么和后面相加必定为负数,所以要舍弃掉,以及计算过的,并当累加大于result时,储存最大结果。
基本思路:遍历数组,按照上面的方法来做即可。