贪心算法(局部最优实现全局最优)第二篇

目录

[1. LeetCode376. 摆动序列](#1. LeetCode376. 摆动序列)

[2. LeetCode334. 递增的三元子序列](#2. LeetCode334. 递增的三元子序列)

[3. LeetCode674. 最长连续递增序列](#3. LeetCode674. 最长连续递增序列)

[4. LeetCode121. 买卖股票的最佳时机](#4. LeetCode121. 买卖股票的最佳时机)


今天我们继续来聊聊贪心算法,因为我在前面也说过贪心算法最重要的就是经验,所以我们今天继续通过刷题的方式来学习贪心算法。

1. LeetCode376. 摆动序列

这道题的意思其实也比较好理解的,就是求一个最长的摆动序列,可以从原数组中删除不符合条件的数。

这道题的话我们先来聊一下思路,因为要求的是最长的子数组。根据题目要求那么是不是说我们每次选的数字都要在有限的分为里面做到尽可能的大或者尽可能的小。为什么要这么做呢?是因为但我们选到最值的时候我们在后面的选择中才可以有更多的选择。

我们看下面这个图,里面有abcdef这几个极值点。我们看,在c和d之间有一个点x1,假设我们在这里选择了这个点的话,那么后面的数都选不了了,因为接下来是要选择比x1小的数。这也是为什么我们每一次都要选择最值的原因。

那么我们代码该怎么设计呢?我们就可以试用一个三指针,通过比较的这三个指针的大小的方式来确定极值点的位置。或者我们也可以观察一下下面这张图,以b点为例子,我们通过后面的点减去前面的点的方式,b减去ab上面的点都是正数,而bc上面的点减去b都是负数,而如果是一个非极值点的话,则都是正数,通过这样的方式我们就得到了极值点,接下来我们就使用这个方式来编写代码。

我们看下面这个代码,前面两个if条件判断都是用来特判的。同时因为原数组里面的值是可能连续好几个相同的,所以我们在这里是需要if判断的,如果相同那么就直接跳过。最后的答案之所以需要+2也是因为我们在这样判断的时候是没有加上两边的端点的,所以我们在这里需要加上。

cpp 复制代码
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int left=0;
        int right=0;
        int sz=nums.size();
        int ret=0;
        if(sz==1||(sz==2&&(nums[0]==nums[1]))) return 1;
        if((nums[0]==nums[sz-1])&&(nums[0]==nums[sz/2])) return 1;
        for(int i=0;i<sz-1;++i)
        {
            right=nums[i+1]-nums[i];
            if(!right) continue;
            if((left*right)<0)
            {
                ret++;
            }
            left=right;
        }
        return ret+2;
    }
};

2. LeetCode334. 递增的三元子序列

这道题的话就比较简单,就是要求我们判断原数组里面有没有三个数是呈现递增关系的,有的话就返回true,没有的话就返回false。

这道题的思路其实挺好想到的,就是在代码编写的时候不要写错了就好。这道题的解法有点像我上面说的三指针。简单来说就是几个判断就好了。

可是这道题使用到了贪心吗?答案是Yes。因为我们的代码有一个思想,那就是每一次判断都在进行筛选,我们都在尽可能的让a和b变小,这样方便我们找到合适的点。

cpp 复制代码
class Solution {
public:
    bool increasingTriplet(vector<int>& nums) {
        int a=nums[0];
        int b=INT_MAX;
        int sz=nums.size();
        for(int i=1;i<sz;++i)
        {
            if(nums[i]>b)
                return true;
            if(a>nums[i])
                a=nums[i];
            else if(nums[i]!=a)
                b=nums[i];
            else
                continue;
        }
        return false;
    }
};

3. LeetCode674. 最长连续递增序列

这道题的话比较简单,就是叫我们从原数组里面找到最长的递增子数组,同时要求是连续的。

这道题的话就比较简单了,就是从头到尾遍历一遍就好,同时记录最大的ret就可以了。

cpp 复制代码
class Solution {
public:
    int findLengthOfLCIS(vector<int>& nums) {
        int ret=1;
        int ret1=1;
        int sz=nums.size();
        for(int i=0;i<sz-1;++i)
        {
            if(nums[i+1]>nums[i])
                ret1++;
            else
                ret1=1;
            if(ret1>ret)
                ret=ret1;
        }
        return ret;
    }
};

4. LeetCode121. 买卖股票的最佳时机

这道题的话也是比较简单的,就是要求我们在原数组里面找到两数之差最大的那两个数。

所以说这道题的话我们就是通过一次遍历然后同时用一个l来不断更新最小值,这样我们就可以取到最大的数了。

这道题贪心的地方在于l一直在更新,在不断地变小。

cpp 复制代码
class Solution {
public:
    int maxProfit(vector<int>& p) {
        int sz=p.size();
        int ret=0;
        int ret1=0;
        int l=INT_MAX;//买
        for(int i=0;i<sz;++i)
        {
            if(l<p[i])
                ret=max(ret,p[i]-l);
            if(l>p[i])
                l=p[i];
        }
        return ret;
    }
};
相关推荐
WZgold1415 分钟前
黄金再创新高!2026 年金价走势预测
大数据·人工智能·经验分享·区块链
TOPGUS5 分钟前
谷歌第三季度财报发布:AI搜索并未蚕食传统搜索,反而正在创造增量
大数据·人工智能·搜索引擎·谷歌·seo·数字营销
MicroTech20257 分钟前
MLGO微算法科技通过 Lindbladians 设计线性微分方程的近似最优量子算法——开放量子系统框架下的量子ODE求解新范式
科技·算法·量子计算
下海fallsea9 分钟前
AI竞争的答案:只买人不买产品
大数据·人工智能
知乎的哥廷根数学学派13 分钟前
基于多尺度特征提取和注意力自适应动态路由胶囊网络的工业轴承故障诊断算法(Pytorch)
开发语言·网络·人工智能·pytorch·python·算法·机器学习
源代码•宸16 分钟前
Leetcode—85. 最大矩形【困难】
经验分享·算法·leetcode·职场和发展·golang·单调栈
平哥努力学习ing28 分钟前
《数据结构》-第八章 排序
数据结构·算法·排序算法
CoovallyAIHub28 分钟前
为AI装上“纠偏”思维链,开源框架Robust-R1显著提升多模态大模型抗退化能力
深度学习·算法·计算机视觉
向量引擎小橙29 分钟前
智能体“组团”时代:通信协议标准化如何颠覆未来协作模式?
大数据·人工智能·深度学习·集成学习
小棠师姐37 分钟前
随机森林原理与实战:如何解决过拟合问题?
算法·机器学习·随机森林算法·python实战·过拟合解决