基于python的leetcode算法介绍之贪心

文章目录

  • 零 算法介绍
  • 一 简单示例 找零钱问题
  • Leetcode例题与思路
    • [605. 种花问题](https://leetcode.cn/problems/can-place-flowers/)
      • 解题思路
      • 题解
    • [409. 最长回文串](https://leetcode.cn/problems/longest-palindrome/)
      • 解题思路
      • 题解
    • [121. 买卖股票的最佳时机](https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/)
      • 解题思路
      • 题解
    • [11. 盛最多水的容器](https://leetcode.cn/problems/container-with-most-water/)
      • 解题思路
      • 题解
    • [763. 划分字母区间](https://leetcode.cn/problems/partition-labels/)
      • 解题思路
      • 题解

零 算法介绍

首先我们需要明确什么算是贪心?

通常,当我们说一个人贪心时,我们是指这个人过分地追求物质财富或利益,常常不顾及他人利益或感受。贪心的人可能会利用他人,甚至不惜损害他人来达到自己的目的。而在算法中,贪心算法指的是一种解决问题的策略,它总是做出在当前状态下看起来最优的选择,期望通过一系列局部最优的选择,达到全局最优的结果。贪心算法的优点是实现简单,运行效率高,但在某些问题上可能无法得到最优解。

贪心算法的基本步骤如下:

  1. 对问题进行分解,将其分解为一系列相互独立的子问题。

  2. 对于每个子问题,找到一个最优解。

  3. 将所有子问题的最优解组合起来,形成问题的最终解。

需要注意的是,贪心算法并不总是能够找到最优解在应用贪心算法时,需要验证问题是否满足贪心选择性质,即通过局部最优的选择,可以导致全局最优的解。如果问题不满足贪心选择性质,那么贪心算法可能无法找到最优解。

贪心算法的应用场景包括:

  1. Dijkstra 算法:用于寻找图中的最短路径。

  2. Huffman 编码:用于构建最优前缀编码。

  3. Kruskal 算法:用于寻找最小生成树。

贪心算法在很多领域都有广泛的应用,但在使用时需要注意其局限性,并在必要时选择其他算法,如动态规划、回溯等。

一 简单示例 找零钱问题

假设你开了间小店,不能电子支付,钱柜里的货币只有 25 分、10 分、5 分和 1 分四种硬币,如果你是售货员且要找给客户 n 分钱的硬币,如何安排才能找给客人的钱既正确且硬币的个数又最少

面对贪心,我们需要首先做一个证明:即证明贪心的方式即为最优解。在这道题目中,我们从最大数开始找零,那么必然可以做到找到零钱数最少【保证每个零钱的数值尽可能大】。

既然得到这个思路,那么题解便自然生成:

def change(n, currency=[25, 10, 5, 1]):"""该程序设计一个找零算法,最后返回应当找回货币的个数Args:n (int): 待找零钱currency (list, optional): 货币的面值有多少. Defaults to [25, 10, 5, 1].Returns:_type_: _description_"""count, i = 0, 0     # count 用作统计货币个数,i 作为统计链表长度while n != 0 and i < len(currency):     # 当还有待找零钱,且货币面值可以继续找零的情况下进行循环count += n // currency[i]           # 当前面值货币可以获得几个n %= currency[i]                    # 剩余待找货币的面值i += 1                              # 判断下一个等级面值的货币的面值return countprint(change(43))
# 6

Leetcode例题与思路

接下来,我们列举关于Leetcode的五道例题,并通过贪心的方式进行求解:

605. 种花问题

假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给你一个整数数组 flowerbed 表示花坛,由若干 01 组成,其中 0 表示没种植花,1 表示种植了花。另有一个数 n ****,能否在不打破种植规则的情况下种入 n ****朵花?能则返回 true ,不能则返回 false

解题思路

这道题目,我们考虑一下如何证明?是否如果当遇到连续的3个0,我们即刻在其中中间的花圃中种植一朵花。而循环遍历整个花田即可保证不能再种植新的花朵了。但需要注意这道题目中的个例:即边界的时候只要两个连续的0就可以了,这该怎么解决呢?详情请看题解:

题解

class Solution:def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:for i in range(len(flowerbed)):left = 0 if i == 0 else flowerbed[i-1]                   # 对左边界的特殊处理right = 0 if i == len(flowerbed)-1 else flowerbed[i+1]   # 对右边界的特殊处理if flowerbed[i] == 0 and left == 0 and right == 0:       # 当前节点为空,且左右为空的情况下flowerbed[i] = 1                                     # 在当前节点种花n -= 1                                               # 剩余花朵减一return n <= 0

409. 最长回文串

给定一个包含大写字母和小写字母的字符串 s ,返回 通过这些字母构造成的 最长的回文串

在构造过程中,请注意 区分大小写 。比如 "Aa" 不能当做一个回文字符串。

解题思路

关于这道题目的解题思路稍微有一些隐式。我们需要验证,构建最长的回味字串需要满足什么条件?即:如果回文子串的长度为偶数,则表示字符串中所有元素的个数都为偶数;如果回文子串的长度为奇数,则除了中心元素外,其他元素必须为偶数。

那么构建最长的回味字串的方法是什么?即对每个字符串取最大偶数的个数,如果还剩下数字,则在加1。转换成代码如下所示:

题解

class Solution:def longestPalindrome(self, s: str) -> int:static = {}for i in s:static[i] = static[i] + 1 if i in static.keys() else 1remain, total = 0, 0for count in static.values():total_, remain_ = divmod(count, 2)remain += remain_total += total_return total * 2 + (0 if remain == 0 else 1)

121. 买卖股票的最佳时机

给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。

你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。

返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0

解题思路

在这道题目中,我们需要判断什么时候买入卖出是最合适的?难道是最小下标和最大下标?那必然不可行。所以我们需要思考一下怎么贪心才可以呢?这道题目其实有一些动态规划的思想在里面,所以思考起来会稍微复杂一些:

我们如何找到能买到最多钱的时候呢?很简单,就是卖出价格减去之前买入价格的时候差值最大。

换句话说,对每个元素减去之前最便宜的价格,就是当前元素的收益,所以我们仅需要这个值的大小即可。

同时,我们仅需要记录在当前元素之前的最小值,就可以通过线性复杂度来求解这道题目。

题解

class Solution:def maxProfit(self, prices: List[int]) -> int:max_value, min_index = 0, 0for i in range(len(prices)):if prices[i] < prices[min_index]:min_index = ielse:max_value = max(max_value, prices[i] - prices[min_index])return max_value

11. 盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

**说明:**你不能倾斜容器。

解题思路

这道题目的思想也比较有意思:当我们下标减小的时候一定会减小容纳的水;但当挡板变高的时候就有可能增大容纳的水的体积。

在有了这个假设的前提下,我们从两端移动挡板,向中间移动。由于容纳体积是由短板决定的,所以我们每次移动短板即可。

转换成代码如下:

题解

class Solution:def maxArea(self, height: List[int]) -> int:i, j, res = 0, len(height) - 1, 0while i < j:if height[i] < height[j]:res = max(res, height[i] * (j - i))i += 1else:res = max(res, height[j] * (j - i))j -= 1return res

763. 划分字母区间

给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s

返回一个表示每个字符串片段的长度的列表。

示例 1:

输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca""defegde""hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。 

解题思路

这道题也是非常有意思的一道题,其核心句其实是**同一字母最多出现在一个片段中。**通过这句话,我们就有确切的分割界限了。但如何做可以通过线性的方式来求解呢?

我给出的思路是统计每个字符出现的区间,如果两个字符串的区间相交,即可融合。于是这就变成了融合区间的题目。由于字符出现的顺序是有序的,所以在合并区间的时候,顺序合并就可以了。

其题解如下:

题解

class Solution:def partitionLabels(self, s: str) -> List[int]:index = {}for i in range(len(s)):if s[i] in index.keys():index[s[i]][1] = ielse:index[s[i]] = [i, i]answer = []key_list = list(index.keys())for i, key in enumerate(key_list):if len(answer) == 0:answer.append(index[key])elif answer[-1][1] > index[key][0]:answer[-1][1] = max(index[key][1], answer[-1][1])else:answer.append(index[key])return [i[1] - i[0] + 1 for i in answer]

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

传输层协议分析--第4关:UDP 包分析

任务描述 本关任务&#xff1a;能够掌握简单的 UDP 包分析。 相关知识 为了更好掌握本章内容&#xff0c;你需要了解的有&#xff1a; UDP 报文的简介&#xff1b;UDP 报文格式&#xff1b;Wireshark 软件中的 UDP 抓包分析。 UDP 简介 UDP&#xff08;User Datagram Pro…

anaconda 安装 使用 pytorch onnx onnxruntime

一&#xff1a;安装 如果不是 x86_64&#xff0c;需要去镜像看对应的版本 安装 Anaconda 输入命令 bash Anaconda3-2021.11-Linux-x86_64.sh 然后输入 yes 表示同意 确认安装的路径&#xff0c;一般直接回车安装在默认的 /home/你的名字/anaconda3 很快就安装完毕。输入 yes…

SCAU:18063 圈中的游戏

18063 圈中的游戏 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC Description 有n个人围成一圈&#xff0c;从第1个人开始报数1、2、3&#xff0c;每报到3的人退出圈子。编程使用链表找出最后留下的人。输入格式 输入一个数n&a…

三防平板定制|5G三防工业平板电脑终端联发科MTK方案

三防平板&#xff0c;顾名思义&#xff0c;是指具备防水、防尘、防坠落等特性的平板电脑。它可以在各种恶劣环境中正常使用&#xff0c;如煤矿、工业制造、户外、建筑等。 三防平板的优势在于其坚固耐用、性能稳定。它通常采用高强度的材料制成&#xff0c;具有较强的抗冲击性和…

如何在 openKylin 上使用 ONLYOFFICE 桌面编辑器

文章作者&#xff1a;ajun ONLYOFFICE 桌面编辑器是一款基于依据 AGPL v.3 许可进行分发的开源办公套件。使用这款应用&#xff0c;您无需保持网络连接状态即可处理存储在计算机上的文档。 本文章基于中国根操作系统 openKylin 操作系统&#xff0c;使用软件商店快速安装与手…

uniapp H5项目使用ucharts的Echart组件方式创建圆环

问题&#xff1a;没有报错但是图表不出来 【 调试了半天圆环图表没有不出来。是因为没有明示设置宽度与高度】 /* 请根据实际需求修改父元素尺寸&#xff0c;组件自动识别宽高 */ .charts-box { width: 100%; height: 300px; } 最终效果 先导入ucharts到项目 uniapp的项目…

零代码敲敲云与钉钉的完美集成,打造智能办公新生态

为满足企业对于高效沟通、协作和工作流程管理日益增长的需求&#xff0c;许多企业都在寻找能够与他们现有的工作平台无缝集成的工具。钉钉作为一款广受欢迎的企业通讯和协同工具&#xff0c;已经成为了众多企业的首选。目前敲敲云已于钉钉完美集成&#xff0c;通过这次集成&…

华为配置BGP的基本示例

组网需求 如图1所示&#xff0c;需要在所有Switch间运行BGP协议&#xff0c;SwitchA、SwitchB之间建立EBGP连接&#xff0c;SwitchB、SwitchC和SwitchD之间建立IBGP全连接。 说明 请确保该场景下互联接口的STP处于未使能状态。因为在使能STP的环形网络中&#xff0c;如果用交…

Navicat关闭自动检查更新版本教程

Navicat关闭自动检查更新版本教程 首先&#xff0c;点击菜单中的工具菜单&#xff0c;弹出了下拉菜单选中为选项点击选项 首先&#xff0c;点击菜单中的工具菜单&#xff0c;弹出了下拉菜单选中为选项 点击选项 去掉勾选上在启动时自动检查更新选项

SpringBoot 集成redis及开发使用、redis客户端工具、redis服务器安装配置、redis启动运行

一 导入redis包 <!--redis数据库--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--spring2.0集成redis所需common-pool2--><depend…

SQLiteStudio安装指南

本博文源于笔者想要打开sqlite3的db文件&#xff0c;于是下载了SQLiteStudio&#xff0c;下载了它&#xff0c;sqlite3的文件随便查看&#xff0c;这里从零开始安装 文章目录 1、搜索官网网址2、开始下载3、开始安装4、开始使用5、总结 1、搜索官网网址 官网地址&#xff1a;…

C#基础——委托、Action和Func的使用

1、委托 委托&#xff08;Delegate&#xff09;是一种类型&#xff0c;可以用来表示对一个或多个方法的引用。委托提供了一种方便的方式来将方法作为参数传递给其他方法&#xff0c;或将方法存储在数据结构中以供以后调用。 不带参数且没返回值的委托 delegate void HDLDelega…

使用docker-compose管理docker服务

使用docker-compose管理docker服务 1&#xff0c;创建docker-compose.yml version: 3 services:javaapp:build: context: ./javaappdockerfile: Dockerfileports:- "9202:9202"- "19202:19202"goapp:build: context: ./goappdockerfile: Dockerfileports…

.netcore 控制台程序,在window操作系统中,怎么获取管理员权限运行此程序

在.NET Core控制台程序中设置管理员权限运行需要以下步骤&#xff1a; 在项目的app.manifest文件中指定管理员权限&#xff1a; <requestedExecutionLevel level"requireAdministrator" />将app.manifest文件设置为嵌入式资源 在程序中获取管理员权限&#…

acl过滤报文配置(hcia)

放火墙就是这样的 原理 问控制列表ACL&#xff08;Access Control List)是由一条或多条规则组成的集合。所谓规则&#xff0c;是 描述报文匹配条件的判断语句&#xff0c;这些条件可以是报文的源地址、目的地址、端口号等。 ACL本质上是一种报文过滤器&#xff0c;规则是过…

操作系统大会2023 | 麒麟信安根植openEuler社区,全场景·同生态·共未来

12月15-16日&#xff0c;以“崛起数字时代 引领数智未来”为主题的操作系统大会 &openEuler Summit 2023在北京举行。产业组织、开放原子开源基金会、学术领袖、行业用户、生态伙伴以及开发者等&#xff0c;共同探讨操作系统产业发展方向和未来机遇&#xff0c;展示最新合作…

SunTorque智能扭矩:扭矩衰减的原因以及如何减缓?

智能扭矩系统-智能拧紧系统-扭矩自动控制系统-SunTorque 在汽车工业中&#xff0c;扭矩衰减是一个令人头痛的问题。它指的是随着车辆使用时间的增长&#xff0c;发动机输出的扭矩逐渐减少。这种现象不仅会影响车辆的动力性能&#xff0c;还会导致燃油经济性下降&#xff0c;甚…

SQL 是一种声明式语言吗?

在学习SQL的时候&#xff0c;我们经常听到这样的说法&#xff1a;SQL是一种声明性语言。你只需要告诉它做什么,不用告诉它怎么做&#xff0c;它就会找到自己的实现方法。也就是说&#xff0c;你只需要用它来描述任务目标&#xff0c;而不需要解释计算过程&#xff0c;这与传统的…

搅拌站智能上料系统,无人值守,均匀布撒!

搅拌站中的骨料上料系统&#xff0c;遇上最新的人工智能技术&#xff0c;会碰撞出怎样的新发展和新突破&#xff1f;今天和砼行们分享一个现场案例&#xff0c;这是思伟软件在某数字化搅拌站中的应用。 上料无人值守 后场上料配合无人地磅系统&#xff0c;仅需1名操作员在控制…

[网络安全]在win2000虚拟机上创建隐藏账户

目录 1.winR->cmd->regedt32 2.新建账号&#xff0c;例如HiddenAccount$($表示在命令行下不现实此用户&#xff09; 3.winR->cmd->regedit 3.将HiddenAccount$删掉 4.最后一步 手工创建隐藏账户 1.你需要一台win2000 2.winR->cmd->regedt32 增加HEY_LOAC…