当前位置: 首页 > article >正文

代码随想录day27 贪心1

题目:455.分发饼干  376.摆动序列   53.最大子序和

需要重做:全部

贪心算法其实就是没有什么规律可言,所以大家了解贪心算法 就了解它没有规律的本质就够了。

不用花心思去研究其规律, 没有思路就立刻看题解

理论基础

贪心的本质是选择每一阶段的局部最优,从而达到全局最优

怎么判断能不能用贪心:举反例。举的出来则不用,举不出来则用贪心。

贪心算法一般分为如下四步:最重要的是想清楚局部最优,能否推倒出全局最优。

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解

455.分发饼干

思路:1.首先排序

2.遍历饼干,从小到大,index记录到第几个孩子。

3.也可以遍历孩子,从大到小,index记录第几个饼干

注意:

另外两种组合也可以写,只是要多加几个变量来记录和控制。

代码:

1.从前往后,遍历饼干,即先满足小胃口

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int index=0;
        for(int i=0;i<s.size();i++){
            if(index<g.size()&&g[index]<=s[i])
            index++;
        }
        return index;
    }
};

2.从前往后,遍历孩子(麻烦)

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int index=0,num=0,time=0;
        for(int i=0;i<g.size()&&(time<=s.size()||time<=g.size());i++){
            time++;
            if(index<s.size()&&s[index++]>=g[i]){
                num++;
                continue;
            }
            i--;
        }
        return num;
    }
};

3.从后往前,遍历孩子.即先满足大胃口

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int num=0,index=s.size()-1;
        for(int i=g.size()-1;i>=0;i--){
            if(index>=0&&g[i]<=s[index]){
                index--;
                num++;
            }
        }
        return num;
    }
};

376. 摆动序列

思路1:1.因为题目说了可以增删元素,所以就在增删的基础上进行搜索。

2.只要是摆动的,就一定是上下上下或下上下上,所以一个波谷就是一个元素。

3.选择curdiff和prediff进行值的更新。res记录

4.考虑几种情况:

        1.正常,全是波峰波谷:prediff<0&&curdiff>0||prediff>0&&curdiff<0

        2.两端低或高中间平:1-2-2-2-1,这时候选择跳过前面的两个2,只记录最后一个2,则条件需要为:prediff<=0&&curdiff>0||prediff>=0&&curdiff<0。(只看最后一个2所处的左右状况就可以写出来)。

        3.上坡中间有多个平坡:1-2-2-2-3-4-4-5。这个时候,prefix的更新时间就必须要在最后一个平坡元素确认的时候才更新,以及正常坡的时候更新。

注意:res初始值为1。prediff可以由curdiff继承来。

代码:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
       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;
    }
};

思路2:动态规划。等学到动态规划再回来写

思路3:在思路2基础上,可以用两棵线段树来维护区间的最大值。

53. 最大子序和

思路:首先想法是暴力,从i开始,里面定义一个count,然后从j开始循环到最后。得到最大值。这样的代码超时了。

然后考虑贪心:局部为正且大即可

我需要的是不断求取为正且大的区间和,所以只要这段区间和的值小于0,我就让区间和count=0;

如何记录最大的?res,如果res<count ;则赋值。

注意:每次count都+=num,只是改变count的值。

思路是:不能让连续和为负数的时候再加上元素,而不是!不能让连续和加上负数

代码:

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int res=INT_MIN;
        int count=0;
        for(int i=0;i<nums.size();i++){
            count+=nums[i];
            if(count>res){
                res=count;
            }
            if(count<0)count=0;
        }
        return res;
    }
};


http://www.kler.cn/a/454002.html

相关文章:

  • 使用vue3搭建前端模拟增删改查
  • Junit如何禁用指定测试类,及使用场景
  • SQL创建和操纵表
  • mysql性能问题排查
  • NLP 中文拼写检测纠正论文 C-LLM Learn to CSC Errors Character by Character
  • Triple三倍
  • 使用 Python 操作 Excel 表格
  • js垃圾回收机制详细讲解
  • IntelliJ Idea常用快捷键详解
  • 数据分析思维(五):分析方法——假设检验分析方法
  • R 语言 | 绘图的文字格式(绘制上标、下标、斜体、文字标注等)
  • 接口测试Day03-postman使用接口用例设计
  • vscode 插件一直提示正在安装的问题
  • Linux 的 Regmap API:简化设备寄存器访问
  • 新一代Web安全技术应用指南
  • 音视频入门知识(二)、图像篇
  • FPGA开发实战之“模块实例化中的端口映射陷阱”
  • HDLBits训练4
  • Flink RocksDB状态缩放加速:RocksDB原生DeleteRange原理简析
  • 云原生相关的 Go 语言工程师技术路线(含博客网址导航)
  • JAVAweb学习日记(三)Ajax
  • Android view 基本的绘制流程
  • 记录Linux Centos 7 安装PostgreSQL 16
  • JZ31 栈的压入、弹出序列
  • Windows脚本命令与Linux Bash脚本命令
  • xctf-WEB-新手练习区Exercise area-Writeup