算法训练day31 | 455.分发饼干 376.摆动序列 53.最大子序和

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.摆动序列

题目链接:摆动序列

视频讲解:贪心算法,寻找摆动有细节!

这是我们思考本题的一个大题思路,但本题要考虑三种情况:

  1. 情况一:上下坡中有平坡
  2. 情况二:数组首尾两端
  3. 情况三:单调坡中有平坡

主要是情况二和三,对于情况二考虑到只有两个节点,我们就令记录的初始值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)
            {
                
            }
        }
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值