贪心算法(1)

目录

 柠檬水找零

题解:

代码:

将数组和减半的最少操作次数(大根堆)

题解:

代码:

最大数(注意 sort 中 cmp 的写法)

题解:

代码:

摆动序列(如何判断波峰、波谷、平台)

题解:

代码:


贪心策略

解决问题的策略:局部最优-> 全局最优

1、把解决问题的过程分为若干步;

2、解决每一步的时候,都选择当前看起来“最优的”解法;

3、希望得到全局最优解。

 柠檬水找零

860. 柠檬水找零 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/lemonade-change/description/

题解:

假设当前顾客付了 5 美元,则无需找零,摊主手中 5 美元的张数+1;

假设当前顾客付了 10 美元,那么摊主需要返还 5 美元

  • 如果摊主手中有 5 美元,则摊主手中 10 美元的张数 +1,且返还顾客 5 美元,即摊主手中 5 美元的张数 -1 ;
  • 如果摊主手中没有 5 美元,说明摊主此时无法找零,直接返回 false;

假设当前顾客付了 20 美元,那么摊主需要返还 15 美元

  • 如果摊主手中有 10 美元 和 5 美元,则摊主手中 10 美元和 5 美元的张数都 -1;
  • 如果摊主手中有 3 张 5 美元,则摊主手中 5 美元的张数 -3;

在可以找零的这两种情况中,就可以体现贪心策略。可以发现在找零的过程中,5 美元经常使用,所以不能让 5 美元的张数太快消耗完,可能会影响后面找零,所以在返还 15 美元的情况下,应该优先返还 1张 10 美元和 1张 5 美元,其次选择返还 3张 5 美元。

代码:

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int ten=0,five=0;
        for(auto x:bills)
        {
            if(x==5)    five++;
            else if(x==10)
            {
                if(five>0)
                {
                    five--;    ten++;
                }
                else    return false;//无法找零
            }
            else//x=20
            {
                if(ten>0 && five>0)//找10+5
                {
                    ten--;  five--;
                }
                else if(five>=3) five-=3;//没有10,找5+5+5
                else    return false;//无法找零
            }
        }
        return true;
    }
};

将数组和减半的最少操作次数(大根堆)

2208. 将数组和减半的最少操作次数 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/minimum-operations-to-halve-array-sum/description/ 

题解:

数组减半的最少操作数,其实就是找到数组中的最大值,并将其减半,为了方便找到数组的最大值,可以使用大根堆,找到堆顶元素,将其减半后再次放回大根堆中,直到数组和减半,就可以得出最少操作数。

代码:

class Solution {
public:
    int halveArray(vector<int>& nums) {
        priority_queue<double> p;
        double sum=0.0;
        for(auto x:nums)
        {
            p.push(x);
            sum+=x;
        }
        sum/=2.0;
        int count=0;
        while(sum>0)
        {
            double tmp=p.top();
            p.pop();
            tmp/=2.0;
            sum-=tmp; 
            p.push(tmp);
            count++;
        }
        return count;
    }
};

最大数(注意 sort 中 cmp 的写法)

179. 最大数 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/largest-number/description/

题解:

以示例一为例,数字 10 和数字 2 拼在一起,会得到数字 102 和数字 210,由于 210 > 102,所以返回 210;

以示例二为例,我们可以对数组排序

数字 3 和 数字 30 拼在一起,得到数字 330 和 数字 303,由于 330 > 303,所以 数字 3 和 数字 30 排序后为 [ 3 , 30 ]

数字 30 和 数字 34 拼在一起,得到数字 3430 和数字 3034,所以排序结果为 [ 34, 30 ],数字 34 再和 数字 3 拼在一起,得到343 和 334,所以最终排序结果为 [ 34 , 3 , 30 ]

用这个规则排序后得到的数组为 [ 9 , 5 , 34 , 3 , 30 ],最终拼到的最大数为 9534330

可以看出排序的规则就是把两个数 a 和 b 拼在一起,拼接后的数为 ab 和 ba,

  • 若 ab > ba,a 就排在 b 前面;
  • 若 ab < ba,b 就排在 a 前面。

为了方便拼接和比较大小,可以把数字都转换为字符串,比较拼接后字符串的字典序

  • 字典序 ab > ba ,a 排在前面;
  • 字典序 ab < ba ,b 排在前面。 

代码:

class Solution {
public:

    string largestNumber(vector<int>& nums) {
        vector<string> str;
        for(auto x:nums)
        {
            str.push_back(to_string(x));
        }
        sort(str.begin(),str.end(),[](const string s1,const string s2)
        {   return s1+s2>s2+s1; });

        string ret;
        for(auto x:str)
            ret+=x;
        if(ret[0]=='0') return "0";
        else return ret;
    }
};

摆动序列(如何判断波峰、波谷、平台)

376. 摆动序列 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/wiggle-subsequence/description/

题解:

以示例二为例,将数字的升降趋势画出图:

可以看出图中存在波峰(极大值),波谷(极小值),波峰和波峰左、右边的数的差值恰好一正一负, 波谷和波谷左、右边的数的差值恰好一正一负, 满足摆动序列的条件,即数组中所有的极大值和极小值构成的子数组就是题目所说的摆动序列,我们只需要得到摆动序列的长度即可

判断一个数和这个数左边的数的差值为 left,和右边的数的差值为 right,判断 left * right 是否小于 0 就可以知道这个数是不是极大/小值

同时,数组最左端和最右端的数也可以视为极大值或极小值,也应该被计入摆动序列中,但最左端的数左边没有数字了,最右端的数右边没有数字了,没办法用 left * right 的积是否小于 0 来判断是否为极大/小值。

  • 针对最端的数,我们将 left 初始化为 0,left * right 为 0,摆动序列的长度 +1,就可以解决最左端的问题;
  • 针对最端的数,在整个数组判断完 left * right 之后,得到的摆动序列的长度 +1 即可。

但是 left * right == 0 还有以下特殊情况,也就是出现了平台

1、数组中连续的几个数的数值相等,即 right = 0,但这几个数总体是呈现上升或下降趋势的,并没有极大/小值

2、数组中连续的几个数的数值相等,即 right = 0,但这几个数中总体上是存在极大/小值的(把这几个数值相同的点视为一个点的话):

 

当 right = 0 时,说明存在平台,我们可以跳过平台, 不要计算 left * right,避免与最左端的情况的判断混淆,跳过平台后,left 是平台左边的差值,right 是平台右边的差值

left * right < 0 则摆动序列的长度 +1(该平台中存在极大/小值,选择平台中的任意一点计入摆动序列即可)。

代码:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int left=0,ret=0,n=nums.size();
        for(int i=0;i<n-1;i++)
        {
            int right=nums[i+1]-nums[i];
            if(right==0)    continue;//平台
            else if(left*right<=0)  ret++;//存在波峰或波谷

            left=right;
        }
        return ret+1;//数组的最左/右端也算是波峰/波谷
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921569.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫——综合实战项目:多平台房源信息采集与分析系统

1. 项目背景与目标 1.1 项目背景 随着房产市场的快速发展&#xff0c;各大平台上充斥着大量房源信息。为了帮助用户快速掌握市场动态&#xff0c;需要通过爬虫技术自动采集多平台数据&#xff0c;清洗后进行存储和分析&#xff0c;为用户提供有价值的洞察。开发者通过这一实战…

数据结构-7.Java. 对象的比较

本篇博客给大家带来的是java对象的比较的知识点, 其中包括 用户自定义类型比较, PriorityQueue的比较方式, 三种比较方法...... 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 .…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备如何使用Docker运行?

在当今的安防监控领域&#xff0c;随着视频监控技术的不断发展和应用范围的扩大&#xff0c;如何高效、稳定地管理并分发视频流资源成为了行业内外关注的焦点。EasyNVR作为一款功能强大的多品牌NVR管理工具/设备&#xff0c;凭借其灵活的部署方式和卓越的性能&#xff0c;正在引…

LSTM原理解读与实战

在RNN详解及其实战中&#xff0c;简单讨论了为什么需要RNN这类模型、RNN的具体思路、RNN的简单实现等问题。同时&#xff0c;在文章结尾部分我们提到了RNN存在的梯度消失问题&#xff0c;及之后的一个解决方案&#xff1a;LSTM。因此&#xff0c;本篇文章主要结构如下&#xff…

Springboot之登录模块探索(含Token,验证码,网络安全等知识)

简介 登录模块很简单&#xff0c;前端发送账号密码的表单&#xff0c;后端接收验证后即可~ 淦&#xff01;可是我想多了&#xff0c;于是有了以下几个问题&#xff08;里面还包含网络安全问题&#xff09;&#xff1a; 1.登录时的验证码 2.自动登录的实现 3.怎么维护前后端…

使用Element UI实现前端分页,前端搜索,及el-table表格跨页选择数据,切换分页保留分页数据,限制多选数量

文章目录 一、前端分页1、模板部分 (\<template>)2、数据部分 (data)3、计算属性 (computed)4、方法 (methods) 二、前端搜索1、模板部分 (\<template>)2、数据部分 (data)3、计算属性 (computed)4、方法 (methods) 三、跨页选择1、模板部分 (\<template>)2、…

VMware Workstation 17.6.1

概述 目前 VMware Workstation Pro 发布了最新版 v17.6.1&#xff1a; 本月11号官宣&#xff1a;针对所有人免费提供&#xff0c;包括商业、教育和个人用户。 使用说明 软件安装 获取安装包后&#xff0c;双击默认安装即可&#xff1a; 一路单击下一步按钮&#xff1a; 等待…

探索PyMuPDF:Python中的强大PDF处理库

文章目录 **探索PyMuPDF&#xff1a;Python中的强大PDF处理库**第一部分&#xff1a;背景第二部分&#xff1a;PyMuPDF是什么&#xff1f;第三部分&#xff1a;如何安装这个库&#xff1f;第四部分&#xff1a;至少5个简单的库函数使用方法第五部分&#xff1a;结合至少3个场景…

go语言range的高级用法-使用range来接收通道里面的数据

在 Go 语言中&#xff0c;可以使用 for ... range 循环来遍历通道&#xff08;channel&#xff09;。for ... range 循环会一直从通道中接收值&#xff0c;直到通道关闭并且所有值都被接收完毕。 使用 for ... range 遍历通道 示例代码 下面是一个使用 for ... range 遍历通…

14.C++STL1(STL简介)

⭐本篇重点&#xff1a;STL简介 ⭐本篇代码&#xff1a;c学习/7.STL简介/07.STL简介 橘子真甜/c-learning-of-yzc - 码云 - 开源中国 (gitee.com) 目录 一. STL六大组件简介 二. STL常见算法的简易使用 2.1 swap ​2.2 sort 2.3 binary_search lower_bound up_bound 三…

5G CPE与4G CPE的主要区别有哪些

什么是CPE&#xff1f; CPE是Customer Premise Equipment&#xff08;客户前置设备&#xff09;的缩写&#xff0c;也可称为Customer-side Equipment、End-user Equipment或On-premises Equipment。CPE通常指的是位于用户或客户处的网络设备或终端设备&#xff0c;用于连接用户…

智能安全配电装置在高校实验室中的应用

​ 摘要&#xff1a;高校实验室是科研人员进行科学研究和实验的场所&#xff0c;通常会涉及到大量的仪器设备和电气设备。电气设备的使用不当或者维护不周可能会引发火灾事故。本文将以一起实验室电气火灾事故为例&#xff0c;对事故原因、危害程度以及防范措施进行分析和总结…

深入理解 LMS 算法:自适应滤波与回声消除

深入理解 LMS 算法&#xff1a;自适应滤波与回声消除 在信号处理领域&#xff0c;自适应滤波是一种重要的技术&#xff0c;广泛应用于噪声消除、回声消除和信号恢复等任务。LMS&#xff08;Least Mean Squares&#xff09;算法是实现自适应滤波的经典方法之一。本文将详细介绍…

如何在分布式环境中实现高可靠性分布式锁

目录 一、简单了解分布式锁 &#xff08;一&#xff09;分布式锁&#xff1a;应对分布式环境的同步挑战 &#xff08;二&#xff09;分布式锁的实现方式 &#xff08;三&#xff09;分布式锁的使用场景 &#xff08;四&#xff09;分布式锁需满足的特点 二、Redis 实现分…

socket连接封装

效果&#xff1a; class websocketMessage {constructor(params) {this.params params; // 传入的参数this.socket null;this.lockReconnect false; // 重连的锁this.socketTimer null; // 心跳this.lockTimer null; // 重连this.timeout 3000; // 发送消息this.callbac…

基于RM开发板32学习日记

环境配置 芯片选型 STM32F407IGH6 配置时钟 12 168 模块 Led 引脚选择 比对原理图 可查看 设置为Out_Put输出 三色同时点亮 合为白色光 HAL_GPIO_WritePin(LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOH, GPIO_PIN_10, GPIO_PIN_SET);GPIOH->ODR…

MacOS下的Opencv3.4.16的编译

前言 MacOS下编译opencv还是有点麻烦的。 1、Opencv3.4.16的下载 注意&#xff0c;我们使用的是Mac&#xff0c;所以ios pack并不能使用。 如何嫌官网上下载比较慢的话&#xff0c;可以考虑在csdn网站上下载&#xff0c;应该也是可以找到的。 2、cmake的下载 官网的链接&…

刷题笔记15

问题描述 小M和小F在玩飞行棋。游戏结束后&#xff0c;他们需要将桌上的飞行棋棋子分组整理好。现在有 N 个棋子&#xff0c;每个棋子上有一个数字序号。小M的目标是将这些棋子分成 M 组&#xff0c;每组恰好5个&#xff0c;并且组内棋子的序号相同。小M希望知道是否可以按照这…

stm32 指定变量存储地址

uint8_t array[10] attribute((at(0x20000000))) 当你使用 attribute((at(地址))) 强制将变量放置在特定地址时&#xff0c;编译器和链接器通常不会自动调整其他变量的地址以避免冲突。这意味着&#xff0c;如果指定的地址已经被其他变量占用&#xff0c;就会发生冲突。 如果…

性能超越Spark 13.3 倍,比某MPP整体快数十秒 | 多项性能指标数倍于主流开源引擎 | 云器科技发布性能测试报告

云器Lakehouse正式发布性能测试报告 &#x1f3c5;离线批处理&#xff1a;在复杂批处理任务中&#xff0c;云器Lakehouse相较Spark表现出13.31倍性能提升。 &#x1f3c5;即席查询&#xff1a;在交互式分析场景下&#xff0c;云器Lakehouse相较Trino表现出9.84倍性能提升。 &am…