代码随想录算法训练营第31天| 455.分发饼干 、 376. 摆动序列、53. 最大子序和
贪心算法的本质就是在每一个阶段都达到局部最优,从而达到全局最优
455.分发饼干
大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个。
可以先将两个数组进行排序,然后将从后向前遍历小孩数组。
不需要两个for循环,使用下标进行自减来控制饼干的遍历即可。
// 先遍历胃口,大胃口吃大饼干
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int res = 0;
int index = s.size() - 1;
sort(g.begin(), g.end());
sort(s.begin(), s.end());
for (int i = g.size() - 1; i >= 0; --i) {
if (index >= 0 && s[index] >= g[i]) {
++res; //满足了一个
--index;
}
}
return res;
}
};
另外也可以使用另一个思路,小饼干喂小胃口
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
int index = 0;
sort(g.begin(), g.end());
sort(s.begin(), s.end());
for (int i = 0; i < s.size(); ++i) {
if (index < g.size() && s[i] >= g[index]) {
++index;
}
}
return index;
}
};
376. 摆动序列
// 贪心
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0; // 当前的一对差值
int preDiff = 0; // 前一对差值
int res = 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)) {
++res;
preDiff = curDiff;
}
}
return res;
}
};
53. 最大子序和
穷举遍历,第一层for循环设置起始位置,第二层for循环遍历数组寻找最大值
// 暴力穷举
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int max = INT32_MIN;
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
sum = 0;
for (int j = i; j < nums.size(); ++j) {
sum += nums[j];
max = max > sum ? max : sum;
}
}
return max;
}
};
也可以使用贪心,如果当前的连续和为负数,就放弃,从下一个元素重新开始计算,因为一个负数加上下一个元素只会使连续和越来越小。
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0; //记录最大的一个和
int max = nums[0];
for (int i = 0; i < nums.size(); ++i) {
if (sum > 0) {
sum += nums[i];
} else {
sum = nums[i];
}
max = (max > sum ? max : sum);
}
return max;
}
};