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

【数据结构】贪心算法:决策的艺术

贪心算法(Greedy Algorithm)是一类在每一步选择中都采取局部最优解的方法,希望最终能够达到全局最优解。通俗地说,贪心算法的思想就是“每一步都尽量做出最好的选择”,以期望整个过程的最终结果也达到最优状态。贪心算法在解决某些特定问题时可以提供快速且高效的方案,因此广泛应用于路径选择、调度、资源分配等领域。

贪心算法的工作原理


算法实战:找零问题

假设我们需要找零的金额为 amount,并且我们有一些面值的硬币。贪心算法的目标是尽可能少地使用硬币来找零。我们将从面值最大的硬币开始找零。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 找零函数
int coinChange(vector<int>& coins, int amount) {sort(coins.rbegin(), coins.rend()); // 从大到小排序int count = 0;for (int coin : coins) {while (amount >= coin) { // 当金额大于或等于硬币面值时amount -= coin; // 减去硬币面值count++; // 记录使用的硬币数量}}return amount == 0 ? count : -1; // 如果找零成功,返回硬币数量,否则返回-1
}int main() {vector<int> coins = {25, 10, 5, 1}; // 硬币面值int amount = 63; // 要找的金额int result = coinChange(coins, amount);if (result != -1) {cout << "最少需要使用的硬币数量: " << result << endl;} else {cout << "无法找零" << endl;}return 0;
}

实践中的挑战与扩展

虽然贪心算法在找零问题中表现出色,但并非所有硬币组合都能保证找到最优解。例如,若面值为 3 和 4 的硬币用于找零 6,贪心算法可能选择 4 + 3,而最优解为 3 + 3。这种情况下,动态规划将更适合解决问题,因为它能考虑所有可能的组合。

但通过动态规划解决的找零问题会考虑所有组合,确保最终解为全局最优。

如果不清除什么是动态规划的话可以去看我另外一篇文章

  • 【数据结构】动态规划:揭开算法优化的秘密
#include <iostream>
#include <vector>
#include <climits>
using namespace std;int coinChangeDP(vector<int>& coins, int amount) {vector<int> dp(amount + 1, INT_MAX);dp[0] = 0; // 基础情况for (int coin : coins) {for (int x = coin; x <= amount; x++) {if (dp[x - coin] != INT_MAX) {dp[x] = min(dp[x], dp[x - coin] + 1);}}}return dp[amount] == INT_MAX ? -1 : dp[amount];
}

贪心算法的优缺点

优点

  1. 高效:贪心算法的时间复杂度通常较低,在需要快速求解的情况下尤为适合。
  2. 实现简单:贪心算法的逻辑清晰,易于实现。它只需一步一步地做出决策,不需要复杂的回溯操作。
  3. 适用于动态数据:在许多实时计算中,贪心算法可以处理不断变化的数据,因为它只关心当前的最佳选择。

缺点

  1. 不能保证全局最优:贪心算法不能保证所有问题的最优解,有时会因局部选择导致全局次优解。
  2. 缺乏灵活性:贪心算法无法回溯,也不适合多步决策或组合问题。
  3. 适用范围有限:贪心算法主要适用于具有贪心选择性质和最优子结构性质的问题。

时空复杂度

如果不清除什么是时空复杂度的话可以去看我另外一篇文章

  • 【数据结构】时间复杂度和空间复杂度是什么?

时间复杂度

贪心算法的时间复杂度通常依赖于具体问题和实现方式。一般来说,它的时间复杂度可以通过以下几个方面进行分析:

  1. 排序:许多贪心算法需要对输入数据进行排序,例如在找零问题中,我们对硬币面值进行了排序。排序的时间复杂度为 ( O ( n log ⁡ n ) (O(n \log n) (O(nlogn),其中 ( n ) (n) (n) 是输入数据的规模。

  2. 遍历:贪心算法通常需要遍历输入数据,选择当前的最佳解。这个过程的时间复杂度通常为 (O(n)) 或 (O(m)),其中 (m) 是选定的子问题规模。

综合考虑,贪心算法的时间复杂度通常为 ( O ( n log ⁡ n ) ) (O(n \log n)) (O(nlogn)) ( O ( n ) ) (O(n)) (O(n)),具体取决于是否需要排序以及遍历的复杂性。

空间复杂度

贪心算法的空间复杂度通常较低,因为它通常不需要额外的存储空间来存储中间结果。常见的空间复杂度为:

  1. 输入数据存储:需要存储输入数据,时间复杂度与输入规模成正比,空间复杂度为 (O(n))。

  2. 常量空间:在大多数贪心算法中,只需使用常量空间来保存临时变量和结果,因此其额外空间复杂度通常为 (O(1))。

因此,贪心算法的空间复杂度一般为 (O(n)),但在许多情况下,其有效空间复杂度为 (O(1))。

复杂度总结

复杂度类型复杂度表达式说明
时间复杂度 ( O ( n log ⁡ n ) ) (O(n \log n)) (O(nlogn)) ( O ( n ) ) (O(n)) (O(n))取决于排序和遍历的复杂性
空间复杂度 ( O ( n ) ) (O(n)) (O(n)) ( O ( 1 ) ) (O(1)) (O(1))通常只需常量空间或输入空间

通过对时空复杂度的分析,我们可以更好地理解贪心算法的性能表现,并在实际应用中做出合理的选择。

常见应用

  • 最短路径问题

    在图算法中,Dijkstra算法就是一种基于贪心策略的算法,用来找到从起点到目标节点的最短路径。该算法在每一步选择当前节点的最短边,从而逐步构建最短路径。Dijkstra算法在权值非负的情况下非常有效,但在权值为负的情况下可能无法得到最优解。

  • 活动选择问题

    活动选择问题是典型的贪心算法应用之一。在一组互不相容的活动中,贪心算法可以帮助选择出最多的活动。例如,若有一组活动需要在不同时间段进行,使用贪心算法可以按活动的结束时间从早到晚排序,依次选择不冲突的活动,从而最大化活动数量。

  • 分数背包问题

    在背包问题中,贪心算法可用于求解“分数背包问题”,即物品可以按任意比例选择。贪心算法在此问题中选择单位重量价值最高的物品直到背包装满,从而实现价值最大化。

  • 区间调度问题

    区间调度问题是一种经典的贪心算法应用,它需要从一组区间中选择互不重叠的最大数量。贪心算法的策略是首先选择结束时间最早的区间,以便为后续区间腾出时间,从而实现最大化选择。

如何判断贪心算法是否适用?

在选择是否应用贪心算法时,通常需要满足以下两个条件:

  • 贪心选择性质:即可以通过局部最优解一步步获得全局最优解。
  • 最优子结构:问题可以通过子问题的最优解构建得到全局最优解。

如果问题不符合这两个条件,那么贪心算法可能不适用,可以考虑动态规划或回溯等更复杂的算法。

贪心算法与动态规划的区别

虽然贪心算法和动态规划都用于解决优化问题,但两者的策略截然不同。动态规划通过记忆化存储和子问题分解来保证全局最优解,而贪心算法则在每一步选择中追求最优。一般而言,当问题具有“贪心选择性质”和“最优子结构”时,贪心算法才适用;否则,动态规划可能是更好的选择。

贪心算法的实现步骤

在实际应用中,贪心算法的实现通常可以分为以下几步:

  1. 选择贪心策略:定义每一步的选择标准,确保每次选择局部最优。
  2. 构建选择序列:基于贪心策略逐步构建问题的解答。
  3. 验证全局解的可行性:确保贪心选择不会影响整体解的正确性。
  4. 执行选择:按照贪心策略选择直到获得最终解。

总结

贪心算法是一种高效、简便的算法,在特定条件下可以迅速求解最优问题。然而,贪心算法并非万全之策,适用于具有贪心选择性质和最优子结构的问题。它的应用领域广泛,涉及路径规划、活动选择、资源分配等多个方面。在选择是否使用贪心算法时,需要全面分析问题特点,确保其满足贪心算法的适用条件。

相关文章:

【数据结构】贪心算法:决策的艺术

贪心算法&#xff08;Greedy Algorithm&#xff09;是一类在每一步选择中都采取局部最优解的方法&#xff0c;希望最终能够达到全局最优解。通俗地说&#xff0c;贪心算法的思想就是“每一步都尽量做出最好的选择”&#xff0c;以期望整个过程的最终结果也达到最优状态。贪心算…...

Linux LVS详解

LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是一个基于Linux操作系统的高性能、可扩展的负载均衡器。以下是对LVS的详细介绍&#xff1a; 一、简介 LVS项目由章文嵩博士在1998年5月发起&#xff0c;是中国国内最早出现的自由软件项目之一…...

LabVIEW显微镜自动对焦系统

在生物医学研究中&#xff0c;显微镜图像的清晰度对于细胞分析非常重要。传统的手动对焦方法容易受到人为因素的影响&#xff0c;因此开发了一种自动对焦技术&#xff0c;以提高图像采集的准确性和效率。 自动对焦方法概述 该系统结合了图像清晰度评估和一维功能优化&#xff…...

基于IP的真实地址生成器

ip-geoaddress-generator 是一个基于 Web 的在线应用程序&#xff0c;能够根据 IP 地址生成真实的随机地址信息。通过多个 API 获取位置数据和随机用户信息&#xff0c;该工具为用户提供了完整的虚拟身份。它由 Next.js 和 Radix UI 构建&#xff0c;具备自动检测当前 IP 地址和…...

下面程序头的三个import语句可以合并或简化么?

下面程序头的三个import语句可以合并或简化么&#xff1f; from tkinter.simpledialog import askinteger from tkinter import * from tkinter import messagebox ——是的&#xff0c;三个import语句可以合并为一个。 合并后的import语句如下所示&#xff1a; from tkinte…...

深度学习--CNN实现猫狗识别二分类(附带下载链接, 长期有效)

1. 代码实现(包含流程解释) 样本量: 8005 # # 1.导入数据集(加载图片)数据预处理# 进行图像增强, 通过对图像的旋转 ,缩放,剪切变换, 翻转, 平移等一系列操作来生成新样本, 进而增加样本容量, # 同时对图片数值进行归一化[0:1] from tensorflow.keras.preprocessing.image …...

Depcheck——专门用于检测 JavaScript 和 Node.js 项目中未使用依赖项的工具

文章目录 Depcheck 是什麽核心功能&#x1f4da;检测未使用的依赖&#x1f41b;检测缺失的依赖✨支持多种文件类型&#x1f30d;可扩展性 安装与使用1. 安装 Depcheck2. 使用 Depcheck Depcheck 的应用总结项目源码&#xff1a; Depcheck 是什麽 来看一个常见错误场景&#x1…...

前端构建工具vite的优势

1. 极速冷启动 Vite 使用原生 ES 模块 (ESM) 在开发环境下进行工作。相比于传统构建工具需要打包所有的文件&#xff0c;Vite 只在浏览器请求模块时动态加载所需的文件。无打包冷启动&#xff1a;无需预先打包&#xff0c;项目启动非常快&#xff0c;尤其对于大型项目效果更明…...

hive查询语句

1.基本语法 SELECT [ALL | DISTINCT]select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BYcol_list] [HAVING where_condition] [ORDER BYcol_list] [CLUSTER BYcol_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number] …...

【AIGC】2024-ECCV-ControlNet++:通过有效的一致性反馈改进条件控制

2024-ECCV-ControlNet: Improving Conditional Controls with Efficient Consistency Feedback ControlNet&#xff1a;通过有效的一致性反馈改进条件控制摘要1. 引言2. 相关工作2.1 基于扩散的生成模型2.2 可控的文本到图像扩散模型2.3 语言和视觉奖励模型 3. 方法3.1. 初步3.…...

Mysql5.7变为GreatSQL 8.0.32-25过程中,SQL语句报错及解决方案

考虑兼容国产化数据库&#xff0c;现需要将Mysql5.7变为GreatSQL&#xff0c;在执行部分sql时&#xff0c;发现在Mysql5.7无报错&#xff0c;在GreatSQL有报错&#xff0c;在此记录一下遇到的几个错误。 1.ERROR 1231 (NO_AUTO_CREATE_USER) 1.1.报错提示 ERROR 1231 (42000…...

Qt 使用QAxObject将QTableView数据导出到Excel表格

这是我记录Qt学习过程的第6篇心得文章&#xff0c;主要是方便自己编写的应用程序导出Excel数据的&#xff0c;走了不少弯路直接上代码。 实现代码&#xff1a; //人员信息导出 ui->pbtn2->setEnabled(false); // 打开文件对话框&#xff0c;选择 excel文件 QString fil…...

fastGpt

参考本地部署FastGPT使用在线大语言模型 1 rockylinx 1 ollama安装 在rockylinux中安装的&#xff0c;ollama由1.5G&#xff0c;还是比较大&#xff0c;所有采用在windows下下载&#xff0c;然后安装的方式&#xff0c;linux安装 tar -C /usr -xzf ollama-linux-amd64.tgz #…...

如何全方位应对服务可用性的挑战

在数字化转型的浪潮中&#xff0c;运维团队正站在企业IT架构的核心位置&#xff0c;面对着前所未有的挑战。服务响应时间和失败率&#xff0c;作为衡量服务质量的重要指标&#xff0c;一直备受关注。然而&#xff0c;在追求这两项指标优化的同时&#xff0c;运维团队还需关注其…...

二进制方式部署k8s集群

目标任务: 1、Kubernetes集群部署架构规划 2、部署Etcd数据库集群 3、在Node节点安装Docker 4、部署Flannel网络插件 5、在Master节点部署组件(api-server,schduler,controller-manager) 6、在Node节点部署组件(kubelet,kube-proxy) 7、查看集群状态 8、运行⼀个测…...

Vivado时序报告七:Report Clock NetworkReport Clock Interaction详解

目录 一、前言 二、Report Clock Network 2.1 Report Clock Network流程 2.2 Report Clock Network报告 三、Report Clock Interaction 3.1 示例设计 3.2 配置选项 3.2.1 Options 3.2.2 Timer_Settings 3.3 Clock Interaction报告 3.3.1 Clock Pair Classification …...

HarmonyOS 组件样式@Style 、 @Extend、自定义扩展(AttributeModifier、AttributeUpdater)

1. HarmonyOS Style 、 Extend、自定义扩展&#xff08;AttributeModifier、AttributeUpdater&#xff09; Styles装饰器&#xff1a;定义组件重用样式   ;Extend装饰器&#xff1a;定义扩展组件样式   自定义扩展&#xff1a;AttributeModifier、AttributeUpdater 1.1. 区…...

信息安全工程师(73)网络安全风险评估过程

一、确定评估目标 此阶段需要明确评估的范围、目标和要求。评估目标通常包括特定的网络系统、信息系统或网络基础设施&#xff0c;评估范围可能涉及整个组织或仅特定部门。明确评估要求有助于确保评估过程的针对性和有效性。 二、收集信息 在评估开始之前&#xff0c;需要对目标…...

在MacOS玩RPG游戏 - RPGViewerPlus

背景知识 由于我一直使用Mac电脑&#xff0c;所以一直对Mac如何玩RPGMV/RPGMZ游戏的方式有进一步的想法。 网上能给出的方案都是自行启动一个HTTP服务进行&#xff0c;进行服务加载。这个方法有效&#xff0c;但兼容性较差。涉及到自定义功能模块的游戏&#xff0c;都会有报错…...

2024.10.27 直接插入排序 非递归后序遍历(复杂版)

直接插入排序 思路&#xff1a;用temp变量存放需要插入前面有序序列的变量&#xff0c;然后用里面的那个for循环寻找到需要插入的位置。 额外注意的点&#xff1a;arr[j1]temp;这个是因为内置循环每次出来之后所指向的位置是我们要插入的位置的前一个&#xff08;-1或者插入…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...