以下是今日份的总结
455 分发饼干
376 摆动序列
53 最大子序和
今天的题目难度不低,尽量还是写一些简洁代码 ^ _ ^
分发饼干
思路:
先排序,通过双指针的方法完成贪心算法
值得注意的是
题目中点明了核心判断条件 s[j]>=g[i]
// 每个孩子最多只能给一块饼干
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int i = 0,j = 0,res = 0;
while(i<g.size()&&j<s.size()){
//核心判断条件 s[j]>=g[i]
if(s[j]>=g[i]){
res++;
i++;
j++;
}
else{
j++;
}
}
return res;
}
摆动序列
思路:
首先获取数组的长度,如果数组长度小于2,则直接返回数组长度作为摆动序列的最大长度。
初始化两个变量 up 和 down 分别表示当前元素为上升和下降的情况下的摆动序列长度,初始值都为1。
从数组的第二个元素开始遍历数组:
如果当前元素大于前一个元素,则意味着当前处于上升的情况,更新 up 为 down + 1。
如果当前元素小于前一个元素,则意味着当前处于下降的情况,更新 down 为 up + 1。
最终返回 up 和 down 中的较大值作为摆动序列的最大长度。
值得注意的是
判断连续上升或者下降的波段个数
int wiggleMaxLength(vector<int>& nums) {
int res = nums.size();
if (res < 2)
return res;
int up = 1, down = 1;
for (int i = 1; i < res; i++) {
//如果当前元素大于前一个元素,则意味着当前处于上升的情况,更新 up 为 down + 1
if (nums[i] > nums[i - 1]) {
up = down + 1;
}
//如果当前元素小于前一个元素,则意味着当前处于下降的情况,更新 down 为 up + 1
if (nums[i] < nums[i - 1]) {
down = up + 1;
}
}
//最终返回 up 和 down 中的较大值作为摆动序列的最大长度
return max(up, down);
}
最大子序和
思路:
如果 -2 1 在一起,计算起点的时候,一定是从 1 开始计算,因为负数只会拉低总和,这就是贪心贪的地方!
局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。
全局最优:选取最大“连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。
值得注意的是
区间的终止位置,其实就是如果 count 取到最大值了,及时记录下来了
int maxSubArray(vector<int>& nums) {
int result = INT32_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;
}
写在最后
----OK,今日份的博客就写到这里,这一期的贪心算法好难想,明天继续加油!!!
—还没看下期的题,但是我的栈还有一节没写;
–追上时间进度了吗?如追,从欠两天变成欠一天!!(笑
-螺旋桨式旋转起飞咯🚁。