本文主要是介绍代码随想录算法训练营第31天 |第八章 贪心算法 part01,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
学习目标:
- 455.分发饼干
- 376. 摆动序列
- 53. 最大子序和
学习内容:
455.分发饼干
class Solution {
public:int findContentChildren(vector<int>& kid, vector<int>& cookie) {sort(kid.begin(),kid.end());sort(cookie.begin(),cookie.end());int index=cookie.size()-1;int result=0;for(int i = kid.size()-1;i>=0;i--){if(index>=0 && cookie[index]>=kid[i]){index--;result++;}}return result;}
};
错误以及注意事项
- 局部最优:大饼干优先满足胃口最大的小朋友。全局最优:最多的小朋友被满足。
376. 摆动序列
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {if(nums.size()<=1) return nums.size();//先考虑空小情况int result=1;//最右边的节点,+1摆动if(nums.size()==1) return 1;int prediff=0; //最左边的节点,prediff=0//最左边加上一个虚拟头节点(平),最右边默认一个摆动。//这样可以完成2个节点的特殊情况。// int curdiff=0;for(int i = 0;i<nums.size()-1;i++){int curdiff = nums[i+1]-nums[i];if((prediff>=0 && curdiff<0)||(prediff<=0 && curdiff>0)){result++;prediff = curdiff; //下两个之间的pre就是上一个cur!!}}return result;}
};
错误以及注意事项
- 局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
- 整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。
- 有很多特殊情况,比如平坡,比如先上升再平坡又接着平坡。
class Solution {
public:int wiggleMaxLength(vector<int>& nums) {int n = nums.size();if (n < 2) return n;int up = 1, down = 1; // 初始化up和downfor (int i = 1; i < n; ++i) {if (nums[i] > nums[i-1]) {up = down + 1; // 如果当前元素大于前一个元素,更新up} else if (nums[i] < nums[i-1]) {down = up + 1; // 如果当前元素小于前一个元素,更新down}// 如果nums[i] == nums[i-1],则不需要更新,继续保持当前的up和down}return max(up, down); // 最大摆动序列长度是up和down中的最大值}
};
更简单通俗的方式解释一下这段代码的工作原理。
摆动序列,就像是一条上上下下的波浪线。在这个序列中,我们希望找到最长的一条波浪线。波浪上升的部分我们叫做“上升摆动”,下降的部分叫做“下降摆动”。
为了找到最长的波浪线,我们用两个标记来帮助我们:
up
:记录到目前为止最长的以上升摆动结束的波浪线的长度。down
:记录到目前为止最长的以下降摆动结束的波浪线的长度。
一开始,波浪线的长度至少是1,因为至少有一个数,所以up
和down
都初始化为1。
然后我们从第二个数开始,一步步地走过数组中的每一个数,检查这个数与前一个数的关系:
- 如果当前的数比前一个数大,那意味着我们找到了一个“上升摆动”。因为波浪线是上下交替的,所以当前的上升摆动肯定是在之前某个下降摆动的基础上加上这一次上升。因此,我们把
down
的值加1来更新up
。 - 同样,如果当前的数比前一个数小,那意味着我们找到了一个“下降摆动”。这时,我们把
up
的值加1来更新down
。
我们这样一直更新up
和down
,直到走完整个数组。最后,最长的波浪线长度就是up
和down
中的最大值。
这种方法的巧妙之处在于,它不直接计算每个可能的波浪线,而是利用上升和下降的规律,通过两个变量就能追踪到最长的波浪线长度。这样做既简洁又有效。
53. 最大子数组和
class Solution {
public: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;}
};
错误以及注意事项
- 我没懂 怎么突然就这样了
学习时间:
2024.2.28 19:00-20:52
这篇关于代码随想录算法训练营第31天 |第八章 贪心算法 part01的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!