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

贪心算法三

> 作者:დ旧言~
> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:了解什么是贪心算法,并且掌握贪心算法。

> 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安!

> 专栏选自:贪心算法_დ旧言~的博客-CSDN博客

> 望小伙伴们点赞👍收藏✨加关注哟💕💕

一、算法讲解

贪心算法的定义:

贪心算法是指在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。

解题的一般步骤是:

  1. 建立数学模型来描述问题;
  2. 把求解的问题分成若干个子问题;
  3. 对每一子问题求解,得到子问题的局部最优解;
  4. 把子问题的局部最优解合成原来问题的一个解。

如果大家比较了解动态规划,就会发现它们之间的相似之处。最优解问题大部分都可以拆分成一个个的子问题,把解空间的遍历视作对子问题树的遍历,则以某种形式对树整个的遍历一遍就可以求出最优解,大部分情况下这是不可行的。贪心算法和动态规划本质上是对子问题树的一种修剪,两种算法要求问题都具有的一个性质就是子问题最优性(组成最优解的每一个子问题的解,对于这个子问题本身肯定也是最优的)。

动态规划方法代表了这一类问题的一般解法,我们自底向上构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,并且以其中的最优值作为自身的值,其它的值舍弃。而贪心算法是动态规划方法的一个特例,可以证明每一个子树的根的值不取决于下面叶子的值,而只取决于当前问题的状况。换句话说,不需要知道一个节点所有子树的情况,就可以求出这个节点的值。由于贪心算法的这个特性,它对解空间树的遍历不需要自底向上,而只需要自根开始,选择最优的路,一直走到底就可以了。

二、算法习题


2.1、第一题

题目链接:674. 最长连续递增序列 - 力扣(LeetCode)

题目描述:

算法思路:

找到以某个位置为起点的最⻓连续递增序列之后(设这个序列的末尾为 j 位置),接下来直接
以 j + 1 的位置为起点寻找下⼀个最⻓连续递增序列。

代码呈现:

class Solution {
public:int findLengthOfLCIS(vector<int>& nums) {int ret = 0, n = nums.size();for (int i = 0; i < n;) {int j = i + 1;// 找到递增区间的末端while (j < n && nums[j] > nums[j - 1])j++;ret = max(ret, j - i);i = j; // 直接在循环中更新下⼀个位置的起点}return ret;}
};

2.2、第二题

题目链接:121. 买卖股票的最佳时机 - 力扣(LeetCode)

题目描述:

算法思路:

由于只能交易⼀次,所以对于某⼀个位置 i ,要想获得最⼤利润,仅需知道前⾯所有元素的最⼩
值。然后在最⼩值的位置「买⼊」股票,在当前位置「卖出」股票即可。

代码呈现:

class Solution {
public:int maxProfit(vector<int>& prices) {int ret = 0; // 记录最终结果for (int i = 0, prevMin = INT_MAX; i < prices.size(); i++) {ret = max(ret, prices[i] - prevMin); // 先更新结果prevMin = min(prevMin, prices[i]);   // 再更新最⼩值}return ret;}
};

2.3、第三题

题目链接:122. 买卖股票的最佳时机 II - 力扣(LeetCode)

题目描述:

算法思路:

由于可以进⾏⽆限次交易,所以只要是⼀个「上升区域」,我们就把利润拿到⼿就好了。

代码呈现:

class Solution {
public:int maxProfit(vector<int>& prices) {// 实现⽅式⼆:拆分成⼀天⼀天int ret = 0;for (int i = 1; i < prices.size(); i++) {if (prices[i] > prices[i - 1])ret += prices[i] - prices[i - 1];}return ret;}
};

2.4、第四题

题目链接:1005. K 次取反后最大化的数组和 - 力扣(LeetCode)

题目描述:

算法思路:分情况讨论,设整个数组中负数的个数为 m 个

a. m > k :把前 k ⼩负数,全部变成正数;

b. m == k :把所有的负数全部转化成正数;

c. m < k :

  • 先把所有的负数变成正数;
  • 然后根据 k - m 的奇偶分情况讨论:
  • 1. 如果是偶数,直接忽略;
    2. 如果是奇数,挑选当前数组中最⼩的数,变成负数

代码呈现:

class Solution {
public:int largestSumAfterKNegations(vector<int>& nums, int k) {int m = 0, minElem = INT_MAX, n = nums.size();for (auto x : nums) {if (x < 0)m++;minElem = min(minElem, abs(x)); // 求绝对值最⼩的那个数}// 分类讨论int ret = 0;if (m > k) {sort(nums.begin(), nums.end());for (int i = 0; i < k; i++) // 前 k ⼩个负数,变成正数{ret += -nums[i];}for (int i = k; i < n; i++) // 后⾯的数不变{ret += nums[i];}} else {// 把所有的负数变成正数for (auto x : nums)ret += abs(x);if ((k - m) % 2) // 判断是否处理最⼩的正数{ret -= minElem * 2;}}return ret;}
};

2.5、第五题

题目链接:2418. 按身高排序 - 力扣(LeetCode)

题目描述:

算法思路:

  • 我们不能直接按照 i 位置对应的 heights 来排序,因为排序过程是会移动元素的,但是names 内的元素是不会移动的。
  • 由题意可知, names 数组和 heights 数组的下标是⼀⼀对应的,因此我们可以重新创建出来⼀个下标数组,将这个下标数组按照 heights[i] 的⼤⼩排序。
  • 那么,当下标数组排完序之后,⾥⾯的顺序就相当于 heights 这个数组排完序之后的下标。之后通过排序后的下标,依次找到原来的 name ,完成对名字的排序。

代码呈现:

class Solution {
public:vector<string> sortPeople(vector<string>& names, vector<int>& heights) {// 1. 创建⼀个下标数组int n = names.size();vector<int> index(n);for (int i = 0; i < n; i++)index[i] = i;// 2. 对下标进⾏排序sort(index.begin(), index.end(),[&](int i, int j) { return heights[i] > heights[j]; });// 3. 提取结果vector<string> ret;for (int i : index) {ret.push_back(names[i]);}return ret;}
};

2.6、第六题

题目链接:870. 优势洗牌 - 力扣(LeetCode)

题目描述:

算法思路:

讲⼀下⽥忌赛⻢背后包含的博弈论和贪⼼策略:
⽥忌:下等⻢ 中等⻢ 上等⻢
⻬王:下等⻢ 中等⻢ 上等⻢

  • a. ⽥忌的下等⻢ pk 不过⻬王的下等⻢,因此把这匹⻢丢去消耗⼀个⻬王的最强战⻢!
  • b. 接下来选择中等⻢ pk ⻬王的下等⻢,勉强获胜;
  • c. 最后⽤上等⻢ pk ⻬王的中等⻢,勉强获胜。

由此,我们可以得出⼀个最优的决策⽅式:

  • a. 当⼰⽅此时最差的⽐不过对⾯最差的时候,让我⽅最差的去处理掉对⾯最好的(反正要输,不如去拖掉对⾯⼀个最强的);
  • b. 当⼰⽅此时
  • c. 最差的能⽐得上对⾯最差的时候,就让两者⽐对下去(最差的都能获胜,为什么要输呢)。每次决策,都会使我⽅处于优势。

代码呈现:

class Solution {
public:vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {int n = nums1.size();// 1. 排序sort(nums1.begin(), nums1.end());vector<int> index2(n);for (int i = 0; i < n; i++)index2[i] = i;sort(index2.begin(), index2.end(),[&](int i, int j) { return nums2[i] < nums2[j]; });// 2. ⽥忌赛⻢vector<int> ret(n);int left = 0, right = n - 1;for (auto x : nums1) {if (x > nums2[index2[left]])ret[index2[left++]] = x;elseret[index2[right--]] = x;}return ret;}
};

三、结束语 

今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。

相关文章:

贪心算法三

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是贪心算法&#xff0c;并且掌握贪心算法。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会坚持。早安! >…...

猫耳大型活动提效——组件低代码化

1. 引言 猫耳前端在开发活动的过程中&#xff0c;经历过传统的 pro code 阶段&#xff0c;即活动页面完全由前端开发编码实现&#xff0c;直到 2020 年接入公司内部的低代码活动平台&#xff0c;满足了大部分日常活动的需求&#xff0c;运营可自主配置活动并上线&#xff0c;释…...

机器学习 Day02,matplotlib库绘图

1.matplotlib图像结构 容器层&#xff1a;画板&#xff0c;画布&#xff0c;坐标系辅助层&#xff1a;刻度&#xff0c;标题&#xff0c;网格&#xff0c;图例等图像层&#xff1a;折线图&#xff08;主讲&#xff09;&#xff0c;饼图&#xff0c;直方图&#xff0c;柱状图等…...

MySQL中有哪几种锁?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL中有哪几种锁&#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL中有哪几种锁&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MySQL 中&#xff0c;锁是用于确保数据的一致性和并发控制的机…...

Unity单例模式更新金币数据

单例模式&#xff08;Singleton Pattern&#xff09;是一种创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。在游戏开发中&#xff0c;单例模式非常适合用于管理全局唯一的数据&#xff0c;比如玩家的金币数量。通过使用单例…...

【javaEE】多线程(进阶)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…...

python从入门到精通(二十四):python爬虫实现登录功能

这里写目录标题 requests实现登录功能selenium实现登录功能 requests实现登录功能 使用 requests 库结合会话&#xff08;Session&#xff09;来尝试登录。不过豆瓣有反爬虫机制&#xff0c;这种方式可能会受到验证码等因素的限制 import requests import re# 豆瓣登录页面 l…...

Flask Jinja语法总结篇

目录 1️⃣ 变量(Variables) 2️⃣ 条件语句(if 语句) 3️⃣ 循环(for 语句) 4️⃣ 过滤器(Filters) 5️⃣ 宏(Macros,类似于函数) 6️⃣ 模板继承(Template Inheritance) 7️⃣ 包含模板(Include) 8️⃣ Flask 结合 Jinja 总结 Jinja 是 Flask 默认使…...

Vue3实战学习(Element-Plus常用组件的使用(输入框、下拉框、单选框多选框、el-image图片))(上)(5)

目录 一、Vue3工程环境配置、项目基础脚手架搭建、Vue3基础语法、Vue3集成Element-Plus的详细教程。(博客链接如下) 二、Element-Plus常用组件使用。 &#xff08;1&#xff09;el-input。(input输入框) <1>正常状态的el-input。 <2>el-input的disable状态。 <3…...

C++ 链表List使用与实现:拷贝交换与高效迭代器细致讲解

目录 list的使用&#xff1a; 构造与赋值 元素访问 修改操作 容量查询 链表特有操作 拼接&#xff08;Splice&#xff09; C11 新增方法 注意&#xff1a; stl_list的模拟实现&#xff1a; 一、链表节点设计的艺术 1.1 结构体 vs 类的选择 二、迭代器实现的精髓 2…...

安当TDE透明加密技术:为Manus大模型构建用户会话数据保护的“安全金库”

摘要 在人工智能技术深度落地的今天&#xff0c;大模型开发者面临的核心挑战已从算法优化转向数据安全。作为垂直领域大模型的代表&#xff0c;Manus凭借其强大的语义理解与个性化交互能力&#xff0c;在金融、医疗、教育等行业获得广泛应用。然而&#xff0c;其海量的用户会话…...

知乎后台管理系统:数据库系统原理实验1——数据库基础概念

实验背景 通过练习绘制语义网络&#xff0c;加深对于基本概念之间关系的理解和掌握。掌握在VISIO中绘制能准确表达基本概念之间关系的语义网络的技能。了解并比较数据模型的Chen’s表示法和UML表示法。理解关系模型设计中的完整性约束的重要性。掌握在Linux操作系统下远程访问…...

docker compose 以redis为例

常见docker compose 命令 》》注意这个是旧版本的&#xff0c;新版本 docker 与compose 之间没有 - 新版本的 docker compose 把 version 取消了 &#xff0c;redis 默认是没有配置文件的 &#xff0c;nginx&#xff0c;mysql 默认是有的 services:redis:image: redis:lat…...

ES C++客户端安装及使用

1. ES 介绍 Elasticsearch &#xff0c; 简称 ES &#xff0c;它是个开源分布式搜索引擎&#xff0c;它的特点有&#xff1a;分布式&#xff0c;零配 置&#xff0c;自动发现&#xff0c;索引自动分片&#xff0c;索引副本机制&#xff0c; restful 风格接口&#xff0c;多…...

【软件工程】一篇入门UML建模图(状态图、活动图、构件图、部署图)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;软件开发必练内功_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…...

应急响应--流量分析

&#xff08;一&#xff09;Cobalt Strike流量特征分析 1.HTTP特征 源码特征&#xff1a; 在流量中&#xff0c;通过http协议的url路径&#xff0c;在checksum8解密算法计算后&#xff0c;32位的后门得到的结果是92&#xff0c;64位的后门得到的结果是93&#xff0c;该特征符…...

name ‘bare_metal_version‘ is not mamba_ssm安装

目录 解决方法&#xff1a; 测试ok&#xff1a; mamba_ssm安装报错&#xff0c;windows 安装时&#xff0c; pip install mamba_ssm name bare_metal_version is not defined mamba代码地址&#xff1a; https://github.com/state-spaces/mamba/tree/main 解决方法&…...

自然语言处理:高斯混合模型

介绍 大家好&#xff0c;博主又来给大家分享知识了&#xff0c;今天给大家分享的内容是自然语言处理中的高斯混合模型。 在自然语言处理这个充满挑战与机遇的领域&#xff0c;我们常常面临海量且复杂的文本数据。如何从这些数据中挖掘出有价值的信息&#xff0c;对文本进行有…...

【C++指南】一文总结C++类和对象【中】

&#x1f31f; 各位看官好&#xff0c;我是egoist2023&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习C类和对象的语法知识。注意&#xff1a;在本章节中&#xff0c;小编会以Date类举例 &#x1f44d; 如果觉得…...

再聊 Flutter Riverpod ,注解模式下的 Riverpod 有什么特别之处,还有发展方向

三年前我们通过 《Flutter Riverpod 全面深入解析》 深入理解了 riverpod 的内部实现&#xff0c;而时隔三年之后&#xff0c;如今Riverpod 的主流模式已经是注解&#xff0c;那今天就让我们来聊聊 riverpod 的注解有什么特殊之处。 前言 在此之前&#xff0c;我们需要先回忆…...

Go语言集成DeepSeek API和GoFly框架文本编辑器实现流式输出和对话(GoFly快速开发框架)

说明 本文是GoFly快速开发框架集成Go语言调用 DeepSeek API 插件&#xff0c;实现流式输出和对话功能。为了方便实现更多业务功能我们在Go服务端调用AI即DeepSeek接口&#xff0c;处理好业务后再用Gin框架实现流失流式输出到前端&#xff0c;前端使用fetch请求接收到流式的mar…...

docker不停机部署

背景 最近做大疆项目时&#xff0c;后台更新部署时&#xff0c;机场和无人机就会掉线。设备自动重连注册时间比较长&#xff0c;应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像&#xff…...

ZLG嵌入式笔记 | ZLG核心板散热设计指引

在嵌入式系统设计中&#xff0c;散热是影响处理器性能与稳定性的关键问题。本文聚焦于高端嵌入式处理器的散热设计&#xff0c;探讨核心板的热设计与系统级热设计方法&#xff0c;以及导热材料和布局的建议&#xff0c;为解决高温问题提供参考。 用高端嵌入式处理器设计系统&am…...

[Java]使用java进行JDBC编程

首先要从中央仓库下载api(类似驱动程序)&#xff0c;为了链接java和mysql 下载jar包&#xff0c;需要注意的是jar包的版本要和mysql保持一致 下面是新建文件夹lib&#xff0c;把jar包放进去&#xff0c;并添加为库 sql固定的情况下运行 import com.mysql.cj.jdbc.MysqlDataSo…...

MySQL进阶-关联查询优化

采用左外连接 下面开始 EXPLAIN 分析 EXPLAIN SELECT SQL_NO_CACHE * FROM type LEFT JOIN book ON type.card book.card; 结论&#xff1a;type 有All ,代表着全表扫描&#xff0c;效率较差 添加索引优化 ALTER TABLE book ADD INDEX Y ( card); #【被驱动表】&#xff0…...

Ubuntu22.04修改root用户并安装cuda

由于本人工作原因&#xff0c;经常会遇到需要给ubuntu打显卡驱动的问题&#xff0c;虽然说不难吧&#xff0c;但是耐不住机器多&#xff0c;重复多次也就烦了&#xff0c;于是抽出了一点时间&#xff0c;并且在deepseek的帮助之下&#xff0c;写了一个自动安装驱动的脚本&#…...

fiddler+雷电模拟器(安卓9)+https配置

一、fiddler配置 1、开启https代理 2、根证书安装&#xff1a;导出证书系统安装 二、模拟器设置 1、设置网络桥接模式 【点击安装】提示安装成功后保存即可 2、开启root&#xff08;开启adb远程调试&#xff09; 3、开启磁盘写入 4、设置WLAN代理 5、证书安装&#xff1a;物…...

STM32-SPI通信协议

目录 一&#xff1a;什么是通信协议&#xff1f; 二&#xff1a;电路结构 1.硬件电路 2&#xff1a;移位 3&#xff1a;时序图 4.交换字节 三&#xff1a;W25Q64简介 硬件电路&#xff1a;​编辑 存储器地址划分 Dlash操作注意事项 状态寄存器 SPI指令集 四&am…...

【CentOS】搭建Radius服务器

目录 背景简介&#xff1a;Radius是什么&#xff1f;Radius服务器验证原理搭建Radius服务器环境信息yum在线安装配置FreeRADIUS相关文件clients.conf文件users文件重启服务 验证 参考链接 背景 在项目中需要用到Radius服务器作为数据库代理用户的外部验证服务器&#xff0c;做…...

Vue中自定义指令:ClickOutside(点击当前模块外的位置)

应用场景 假设我们有一个下拉框组件&#xff0c;当下拉框展开的时候&#xff0c;点击下拉框之外的元素可以自动关闭下拉框。 一 ClickOutside代码示例 在vue3中使用ClickOutside // 导入自定义指令 import { ClickOutside as vClickOutside } from element-plus;// 绑定指令…...