455.分发饼干
题目链接:分发饼干
视频讲解:贪心算法,你想先喂哪个小孩?
本题思路是现将饼干和小孩排序,然后用大饼干满足胃口大的小孩并记录满足小孩的数量。一定要先遍历胃口再遍历饼干,外面的 for 是里的下标 i 是固定移动的,而 if 里面的下标 index 是符合条件才移动的。如果 for 控制的是饼干, if 控制胃口,就是出现如下情况 :if 里的 index 指向 胃口大的, for 里的 i 指向饼干比胃口小,因为饼干满足不了胃口,所以 i 持续向前移动,而 index 走不到s[index] >= g[i]
的逻辑,所以 index 不会移动,那么当 i 持续向前移动,最后所有的饼干都匹配不上。所以 一定要 for 控制 胃口,里面的 if 控制饼干。
// 时间复杂度:O(nlogn)
// 空间复杂度:O(1)
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int ret = 0;
int idx = s.size() - 1;
for (int i = g.size() - 1; i >= 0; --i) // 先遍历胃口
{
if (idx >= 0 && s[idx] >= g[i]) // 再遍历饼干
{
idx--;
ret++;
}
}
return ret;
}
};
376.摆动序列
题目链接:摆动序列
视频讲解:贪心算法,寻找摆动有细节!
这是我们思考本题的一个大题思路,但本题要考虑三种情况:
- 情况一:上下坡中有平坡
- 情况二:数组首尾两端
- 情况三:单调坡中有平坡
主要是情况二和三,对于情况二考虑到只有两个节点,我们就令记录的初始值ret=1,默认最右端有一个峰值。对于情况三我们可以在摆动时才更新pre,这样pre在有平坡时就不会变化,不影响结果。
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int pre = 0;
int cur = 0;
int ret = 1; // 只有两个元素的情况,让ret=1默认最右边有一个峰值
for (int i = 0; i < nums.size() - 1; i++)
{
cur = nums[i + 1] - nums[i];
if ((pre >= 0 && cur < 0) || (pre <= 0 && cur > 0))
{
ret++;
pre = cur; // 只有满足条件时才更新pre
}
}
return ret;
}
};
53.最大子序和
题目链接:最大子序和
视频讲解:贪心算法的巧妙需要慢慢体会!
本题贪心算法主要是记录“连续和”,当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。从代码角度上来讲:遍历 nums,从头开始用 count 累积,如果 count 一旦加上 nums[i]变为负数,那么就应该从 nums[i+1]开始从 0 累积 count 了,因为已经变为负数的 count,只会拖累总和。
// 时间复杂度:O(n)
// 空间复杂度:O(1)
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> v;
int sum = 0;
for (int i = 0; i < nums.size(); ++i)
{
int tmp = 0;
tmp = sum;
v.push_back(nums[i]);
sum += i;
if (tmp > sum)
{
}
}
}
};