【算法】(Python)贪心算法

贪心算法:

  • 又称贪婪算法,greedy algorithm。
  • 贪心地追求局部最优解,即每一步当前状态下最优选择。
  • 试图通过各局部最优解达到最终全局最优解。但不从整体最优上考虑,不一定全局最优解。
  • 步骤:从初始状态拆分成一步一步的,每一步确保当前状态最优解,再下一步。
  • 关键:具体的贪心策略(选择能产生问题最优解的最优度量标准)。
  • 使用条件:贪心选择(一个问题最优解可通过一系列局部最优解达到,每一步可依赖以前的选择,不可回溯),最优子结构(一个问题最优解包含其子问题的最优解)。

案例:

1、(难度:简单)【力扣】1710. 卡车上的最大单元数

 解题思路:每一步优先挑选当前可装载的最大单元数量的箱子。

  1. 将列表按单元数量(元素中下标为1的值)降序排列。
  2. 遍历列表中所有元素,
  3. 若当前元素的箱子最大数量已经达到指定总数量,则单元总数=指定总数量*单元数量,并结束,返回单元总数。
  4. 若当前箱子最大数量在指定总数量之内,则当前箱子最大数量*单元数量,累加到单元总数中,剩余指定总数量=指定总数量-当前箱子最大数量;
  5. 再判断列表中下一个元素,
  6. 直到遍历完列表中所有元素,或者达到指定总数量,返回单元总数。

 知识点:列表.sort(key=排序条件, reverse=True):列表按照排序条件降序排列。

class Solution:
    def maximumUnits(self, boxTypes: List[List[int]], truckSize: int) -> int:
        # 将列表按单元数量(即各元素下标为1的值)降序排列
        boxTypes.sort(key=lambda x: x[1], reverse=True)
        
        total = 0         # 记录可装载的单元总数
        # 遍历列表,指定最大数量依次减去最大箱子数量计算剩余数量,并统计单元总数
        # i为箱子数量,j为每个箱子的单元数量
        for i, j in boxTypes:
            if i >= truckSize:
                total += truckSize * j
                break
            total += i * j
            truckSize -= i
        return total

2、(难度:中等)【力扣】714. 买卖股票的最佳时机含手续费

解题思路:买卖为一次交易、计算一次手续费,则买入时计算手续费。买入价尽可能当前最低价,卖出价尽可能当前最高价。

  1. 初始买入价为列表第一日价格(含手续费),
  2. 依次遍历列表中每日价格,
  3. 若当前价(含手续费)<买入价,即当前价格比前一天低,则当前价(含手续费)为新的买入价。若当前价(不含手续费)>买入价,则假装卖出,计算利润(若前一日也假装卖出则利润加上当前价与前一日的差价),并假装当天免手续费买入,即当天价(不含手续费)为买入价,
  4. 下一日价格,当前价再与买入价比较。
  5. 遍历完列表所有元素,返回总利润。
class Solution:
    def maxProfit(self, prices: List[int], fee: int) -> int:
        profit = 0                # 记录总收益
        buy = prices[0] + fee     # 初始买入
        # 遍历每个价格
        for i in prices:
            # 若当前价+手续费<买入价,则当前价买入
            if i + fee < buy:
                buy = i + fee
            # 当前价格>买入价,(假装卖出)计算利润(当前价与买入价的差),
            # 并假装以当前价免手续费买入(若明天价比当前价高,明天收益就是明天价与当前价之间的差)
            elif i > buy:
                profit += (i - buy)
                buy = i
        return profit

注:本题其他解题方法:动态规划。本文忽略。

3、(难度:困难)【力扣】871. 最低加油次数

解题思路:一个优先队列记录每个加油站的加油量(降序,最大油量在前)。计算每到一个地方的剩余油量,若不足则优先使用最大油量加油。

  1. 遍历每个地方和目的地(n+1),
  2. 计算从上一个位置到达当前地方后的剩余油量,
  3. 若剩余油量不足,则依次从优先队列取出最大油量加油,每加一次统计一次,直到加满或优先队列为空(即没有油可加),
  4. 若加完油后剩余油量仍不足,则无法到达目的地,返回-1,
  5. 每到达一个加油站,将加油量添加到优先队列,并将当前地方设为上一位置,用于下一个地方计算判断油量。

 知识点:二维数组[子数组下标][子数组中元素下标]:获取二维数组中元素。二维数组:数组中的元素类型仍为数组。

               python中heapq库用于操作堆(最小堆,最大堆),应用于优先队列和堆排序。此处为优先队列。

               heapq.heappush(队列, 元素):往优先队列添加元素,自动生成最小堆(父节点小于所有子节点,左右子节点无大小要求)。元素前加负号“-”,则各元素负数后的最小堆,类似最大堆,取出时前面也加负号“-”即为最大值。

               heapq.heappop(队列):从优先队列中取出最小值。

class Solution:
    def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int:       
        import heapq
        res = 0               # 统计加油次数
        fuel_list = []        # 油量优先队列(最大的在前),记录每个加油站的加油量
        fuel = startFuel      # 记录目前油量
        pre = 0               # 记录上一个位置
        # 遍历每个加油站和目的地
        n = len(stations)
        for i in range(n + 1):
            # 记录当前位置,若加油站则为元素中下标为0的值,若目的地则为target
            if i < n: cur = stations[i][0]
            else: cur = target
            # 计算达到当前位置,剩余油量
            fuel -= cur - pre
            # 若剩余油量<0,且油量优先队列中有元素,依次按最大油量加油,直到加满或油量优先队列为空
            while fuel < 0 and fuel_list:
                # 油量优先队列为了从大到小排列,元素是负数
                fuel += (-heapq.heappop(fuel_list))           # 从优先队列取出最大值
                res += 1
            # 若加油后,剩余油量仍<0,说明即使加满油也到不了目的地
            if fuel < 0: return -1
            # 每到一个加油站,将油量添加到油量优先队列中
            if i < n:
                # 油量优先队列为了从大到小排列,元素是负数
                heapq.heappush(fuel_list, -stations[i][1])    # 添加到优先队列(最大堆)
                pre = cur
        return res

以上是从上次位置到达该加油站后剩余油量判断,也可以直接判断从起始位置到达各加油站时油量是否充足,若不足则取出油量优先队列的最大值加油。

class Solution:
    def minRefuelStops(self, target: int, startFuel: int, stations: List[List[int]]) -> int:
        import heapq
        h = []         # 油量优先队列(最大的在前),记录每个加油站的加油量
        res = 0        # 统计加油次数
        # 遍历每个加油站和目的地
        for long, fuel in stations + [[target, 0]]:
            # 若油量不够,则从优先队列取出最大油量加油
            while startFuel < long:
                # 若优先队列为空(即没有油可加),即无法到达目的地
                if not h: return -1
                startFuel -= heapq.heappop(h)
                res += 1
            # 每到一个加油站,就将油量添加到优先队列
            heapq.heappush(h, -fuel)
        return res

注:本题其他解题方法:动态规划。本文忽略。

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

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

相关文章

01简介——基于全志V3S的Linux开发板教程笔记

声明&#xff1a;本笔记内容为个人在使用自制的基于全志V3S的Linux开发板的学习笔记文章&#xff0c;仅用于记录学习与开发过程中的问题处理过程、方法操作记录、参考的网络资源等内容。 一、前言 一次偶然的机会&#xff0c;发现了全志V3S这款芯片&#xff0c;基于Cortex-A7内…

【数据库】elasticsearch

1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片&#xff08;Shard&#xff09;&#xff1a; 将索引数据分割成多个部分&#xff0c;每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理&#xff0c;从而提高系统的扩展性和性能。 在创建索…

C6.【C++ Cont】cout的格式输出

目录 1.头文件 2.使用 1.控制宽度和填充 setw函数(全称set field width设置字段宽度) setfill函数(全称Set fill character设置填充字符) 2.控制数值格式 3.控制整数格式 4.控制对齐方式 1.头文件 用cout进行格式化输出前,先引用头文件iomanip(全称input&output m…

【Unity】Unity拖拽在Android设备有延迟和卡顿问题的解决

一、介绍 在制作Block类游戏时&#xff0c;其核心的逻辑就是拖拽方块放入到地图中&#xff0c;这里最先想到的就是Unity的拖拽接口IDragHandler,然后通过 IPointerDownHandler, IPointerUpHandler 这两个接口判断按下和松手&#xff0c;具体的实现逻辑就是下面 public void On…

零基础快速入门MATLAB

文章目录 前言1.向量1.1 创建方式1.1.1 直接输入各个元素1.1.2 冒号创建1.1.3 使用linspace函数 1.2 向量的运算1.2.1 加法1.2.2 相乘 2.输入与输出2.1 输入函数--input()2.2 输出函数 3.分支结构3.1 if语句3.2 switch语句 4.循环结构4.1 for循环4.2 while循环4.3 特殊语句 5.函…

gitmakegdb

git git reset 命令 | 菜鸟教程 (runoob.com) 像嫁接一样 make Makefile | 爱编程的大丙 (subingwen.cn) # 举例: 有源文件 a.c b.c c.c head.h, 需要生成可执行程序 app ################# 例1 ################# app:a.c b.c c.cgcc a.c b.c c.c -o app################# 例…

记一次微信云托管搭建Redis服务

背景 最近在做一个微信小程序&#xff0c;规划服务全部部署在云托管上面&#xff0c;本次使用了对象存储、mysql、java服务、Redis服务&#xff08;pc端用的&#xff09;。 由于对部署Redis不理解&#xff0c;查看了官方文档&#xff0c;首先看到的是这个架构图&#xff0c;看…

gerrit 搭建遇到的问题

1、启动Apache&#xff0c;端口被占用 : AH00072: make sock: could not bind to address (0S 10048)通常每个套接字地址(协议/网络地址/端口)只允许使用一次。: AH00072: make sock: could not bind to address 0.0.0.:443 a AH00451: no listening sockets available, shutti…

STM32之看门狗

STM32有独立看门狗&#xff08;IWDG&#xff09;和窗口看门狗(WWDG)。 采用窗口看门狗&#xff08;WWDG&#xff09;&#xff0c;有一个死前中断&#xff0c;可以用来作一个报警的功能。 独立看门狗超时时间计算公式 假设LSI是32KHz,超时时间等于 预分频系数&#xff08;4&…

Python爬虫基础-正则表达式!

前言 正则表达式是对字符串的一种逻辑公式&#xff0c;用事先定义好的一些特定字符、及这些特定字符的组合&#xff0c;组成一个“规则的字符串”&#xff0c;此字符串用来表示对字符串的一种“过滤”逻辑。正在在很多开发语言中都存在&#xff0c;而非python独有。对其知识点…

lvgl白屏问题(LCD长时间白屏)和优化lvgl

开机白屏时间过长 -- 这里我们不考虑是lvgl占的内存太大的问题&#xff0c;这里考虑的是为什么lcd屏幕启动后会有长时间的白屏。 首先我们要了解lvgl的相关操作&#xff0c;主要集中在一个函数中。只有程序执行到了这个函数&#xff0c;lvgl的屏幕才会显现出来 总结来说就是l…

雷池社区版 7.1.0 LTS 发布了

LTS&#xff08;Long Term Support&#xff0c;长期支持版本&#xff09;是软件开发中的一个概念&#xff0c;表示该版本将获得较长时间的支持和更新&#xff0c;通常包含稳定性、性能改进和安全修复&#xff0c;但不包含频繁的新特性更新。 作为最受欢迎的社区waf&#xff0c…

【系统分析师】-案例综合知识大全

1、表示处理流程的工具 图形工具、表格工具和语言工具。 其中常见的图形工具包括程序流程图、IPO 图、盒图、问题分析图、判定树&#xff0c; 表格工具包括判定表&#xff0c; 语言工具包括过程设计语言 2、用例建模过程 识别参与者、合并需求获得用例、细化用例描述和调…

python爬取旅游攻略(1)

参考网址&#xff1a; https://blog.csdn.net/m0_61981943/article/details/131262987 导入相关库&#xff0c;用get请求方式请求网页方式&#xff1a; import requests import parsel import csv import time import random url fhttps://travel.qunar.com/travelbook/list.…

G. Welcome to Join the Online Meeting!【CCPC2024哈尔滨站】

G. Welcome to Join the Online Meeting 思路: 挺简单的BFS思路 图论题写的比较少&#xff0c;算是补题吧 代码: #include <bits/stdc.h> #define endl \n #define int long long #define pb push_back #define pii pair<int,int> const int MOD 1e97; const …

《图像滤波算法综述》

一、引言 在数字图像处理的世界里&#xff0c;滤波是一项关键技术。通过对图像应用滤波算法&#xff0c;可以有效去除噪声、增强图像的细节并显著提升图像质量。本篇内容将为您深入介绍几种常见的图像滤波算法及其原理和应用场景。 二、图像滤波算法的分类 图像滤波算法可以…

RK3568开发板静态IP地址配置

1. 连接SSH MYD-LR3568 开发板设置了静态 eth0:1 192.168.0.10 和 eth1:1 192.168.1.10&#xff0c;在没有串口时调试开发板&#xff0c;可以用工具 SSH 登陆到开发板。 首先需要用一根网线直连电脑和开发板&#xff0c;或者通过路由器连接到开发板&#xff0c;将电脑 IP 手动设…

(蓝桥杯C/C++)——基础算法(上)

目录 一、二分法 1.二分法简介 二分法简介-解题步骤 2.整数二分-简介 整数二分-模板 3.浮点二分-简介 浮点二分-模板 4.二分答案-简介 二分答案-模板​​​​​​​ 二、位运算 1.位运算简介 2.常见的位运算 按位与AND(&) 按位或OR( | ) 按位异或…

【RAG系列】KG-RAG 用最简单的方式将知识图谱引入RAG

目录 前言 一、引入知识图谱的作用 二、引入知识图谱的挑战 三、KG-RAG的理论 query多跳有限性 知识局部密集性 四、KG-RAG的方法 向量入库 向量相似搜索 扩展子图 LLM Rerank LLM response 五、效果比对 六、源码 总结 前言 本文介绍一种比较新颖的RAG范式&am…

6.《双指针篇》---⑥和为S的两个数字(中等但简单)(牛客)

题目传送门 方法一&#xff1a;暴力解法。双循环 方法二&#xff1a;双指针&#xff08;推荐&#xff09; 1.定义一个顺序表&#xff0c;定义左右双指针 2.while循环。判断array[left] array[right] 的值。 3.若等于则将这两个值加入数组。并break 4.若大于则right-- 5.若小于…