贪心算法实战篇2

news2025/6/4 11:07:41

文章目录

  • 前言
  • 序列问题
    • 摆动序列
    • 单调递增的数字
  • 贪心解决股票问题
    • 买卖股票的最佳时机II
  • 两个维度权衡问题
    • 分发糖果
    • 根据身高重建队列

前言

今天继续带大家进行贪心算法的实战篇2,本章注意来解答一些运用贪心算法的中等的问题,大家好好体会,怎么从构建局部最优到全局最优的。一文带大家弄懂。本文用于记录自己的学习过程,同时向大家进行分享相关的内容。本文内容参考于代码随想录同时包含了自己的许多学习思考过程,如果有错误的地方欢迎批评指正!

image-20250516165753896

序列问题

摆动序列

376. 摆动序列 - 力扣(LeetCode)

image-20250516170811819

**相关技巧:**首先我们先来理解题意要我们干什么,就是在一个序列中,找出其摆动序列,即其差值的形式为正负交替的,找出其最长子序列的长度。就是我们可以通过删除一些元素来使其满足摆动序列的性质,这里就是要求其最大的长度。

理解了题意再来看我们该怎么做这道题。我们通过什么样的形式来删除一些不必要的元素呢?举个例子来说,当序列为1,2,3,4时,可以很明显的看出最大长度为2,但是是哪个组合呢?1,2可以,1,3可以,1,4也可以。这里我们注意,我们以最后的作为答案。即我们一直增的话,我们就找到山顶,一直降的话我们就找到山谷,像爬山一样,找出山顶山谷的过程,这就是我们使用的贪心策略。

这里代码实现的关键就是我们怎么找到山谷山顶,其实很简单,我们所需要的摆动序列差值是正负摆动的,即两者差小于零,但是差值为零就不算摆动了,所以这样我们就能够很容易的写出代码了,如下所示。

class Solution:
    def wiggleMaxLength(self, nums: List[int]) -> int:
        if len(nums) <= 1:
            return len(nums)  # 如果数组长度为0或1,则返回数组长度
        preDiff,curDiff ,result  = 0,0,1  #题目里nums长度大于等于1,当长度为1时,其实到不了for循环里去,所以不用考虑nums长度
        for i in range(len(nums) - 1):
            curDiff = nums[i + 1] - nums[i]
            if curDiff * preDiff <= 0 and curDiff !=0:  #差值为0时,不算摆动
                result += 1
                preDiff = curDiff  #如果当前差值和上一个差值为一正一负时,才需要用当前差值替代上一个差值
        return result

单调递增的数字

738. 单调递增的数字 - 力扣(LeetCode)

image-20250516170836651

**相关技巧:**这题题目还是很好理解了,就是找到单调递增的最大数,首先我们来看看,我们该怎么去遍历这个数,如果我们从左往右进行遍历,当前数小于上一位了,修改上一位,可是修改之后呢?上一位因为修改又小于上上一位了怎么办?那我们在来看从右往左进行遍历,当前位比前一小,说明需要修改前一位,修改之后,我们再将修改位之后的都变成9,这样我们就不会破坏递增性质了。

比如说就是332,第2位的3比2大,不符合递增性质,所以,3-1变成2,修位之后都变成9,就变成了329,然后再看第1位的3比第2位的2大,所以再修改,3-1变成2,第一位的3之后的都变成9,就变成了299,一次遍历就能够得到我们需要的,代码如下。

class Solution:
    def monotoneIncreasingDigits(self, n: int) -> int:
        # 将整数转换为字符串
        strNum = list(str(n))

        # 从右往左遍历字符串
        for i in range(len(strNum) - 1, 0, -1):
            # 如果当前字符比前一个字符小,说明需要修改前一个字符
            if strNum[i - 1] > strNum[i]:
                strNum[i - 1] = str(int(strNum[i - 1]) - 1)  # 将前一个字符减1
                # 将修改位置后面的字符都设置为9,因为修改前一个字符可能破坏了递增性质
                strNum[i:] = '9' * (len(strNum) - i)

        # 将列表转换为字符串,并将字符串转换为整数并返回
        return int(''.join(strNum))

贪心解决股票问题

买卖股票的最佳时机II

122. 买卖股票的最佳时机 II - 力扣(LeetCode)

image-20250516170859647

**相关技巧:**首先我们要清楚,我们一天只能持有一支股票,并且我们一天中只有买股票和卖股票的操作。那么我们需要如何才能获得最大的利润呢?

首先一个非常重要的就是要知道,利润是可以分解的。

就是说我们假如第 0 天买入,第 3 天卖出,那么利润为:prices[3] - prices[0]。其本质相当于(prices[3] - prices[2]) + (prices[2] - prices[1]) + (prices[1] - prices[0])。

**此时就是把利润分解为每天为单位的维度,而不是从 0 天到第 3 天整体去考虑!**那么根据 prices 可以得到每天的利润序列:(prices[i] - prices[i - 1])…(prices[1] - prices[0])。

这个时候再来看,我们需要获得最大的利润是不是就只需要将每天正的利润加起来即可。其实贪心也体现再其中,我只要赚了就卖掉,就是很典型的贪心思想了。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        result = 0
        for i in range(1, len(prices)):
            result += max(prices[i] - prices[i - 1], 0)
        return result

两个维度权衡问题

分发糖果

135. 分发糖果 - 力扣(LeetCode)

image-20250516170945614

**相关技巧:**首先看题,我们的第一想法肯定就是一次遍历,如果其分数比左右两边大,就取大的加1,但是这样我们同时兼顾就会造成顾此失彼的状态,比如说如下的情况

image-20250528163442809

一开始都是1个,即是1,1,1,1,1,1,1。按照我们刚才所说的同时比较两边就会得到最终的1,1,1,2,2,2,1。但是这最终得到的是不符合题意的,最高分的5应该比边上的大,但最终得到的却不是的。

所以我们取做的时候就要分维度比较讨论。首先从左往右遍历比较,并且比较的是其右边的数,然后从右往左遍历比较,并且比较的是其左边的数,最终计算糖果数量。代码如下,还是比较容易理解的。

class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        candies = [1] * n
        
        # Forward pass: handle cases where right rating is higher than left
        for i in range(1, n):
            if ratings[i] > ratings[i - 1]:
                candies[i] = candies[i - 1] + 1
        
        # Backward pass: handle cases where left rating is higher than right
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candies[i] = max(candies[i], candies[i + 1] + 1)
        
        return sum(candies)

根据身高重建队列

406. 根据身高重建队列 - 力扣(LeetCode)

image-20250516171010146

**相关技巧:**同样的这回我们仍旧是需要从两个维度来进行考量。首先考虑身高,然后再考虑k,我们首先按照身高排序,然后执行插入操作,按身高先插入,再按k值进行插入,当k值相同的时候,身高矮的在前面。其实就是两次排序的过程,先按身高排,再按k值排。其实其贪心策略就如下:

局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性

全局最优:最后都做完插入操作,整个队列满足题目队列属性

实现的代码如下,这还是比较好理解的。

class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
    	# 先按照h维度的身高顺序从高到低排序。确定第一个维度
        # lambda返回的是一个元组:当-x[0](维度h)相同时,再根据x[1](维度k)从小到大排序
        people.sort(key=lambda x: (-x[0], x[1]))
        que = []
	
	# 根据每个元素的第二个维度k,贪心算法,进行插入
        # people已经排序过了:同一高度时k值小的排前面。
        for p in people:
            que.insert(p[1], p)
        return que

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

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

相关文章

Java 大视界 -- Java 大数据机器学习模型在元宇宙虚拟场景智能交互中的关键技术(239)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

高速串行接口

1.网口设计方案 上图中给出了两种网口设计方案&#xff0c;最上面是传统设计方式&#xff0c;下面是利用GT作为PHY层的设计&#xff0c;然后FPGA中设计协议层和MAC层。 2.SRIO SRIO的本地操作和远程操作 3.其他高速接口 srio rapid io aurora8b10b aurora64b66b pcie s…

学习STC51单片机23(芯片为STC89C52RCRC)

每日一言 成功的路上从不拥挤&#xff0c;因为坚持的人不多&#xff0c;你要做那个例外。 通过单片机发指令给ESP8266进行通信 通信原理(也是接线原理) 代码如下 代码解释一下&#xff0c;因为我们的指令是字符数组&#xff08;c语言没有字符串的概念&#xff09;&#xff0c;…

一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (一)

整体链路 [应用服务器] --> [Filebeat] --> [Logstash] --> [Elasticsearch] --> [Kibana] 组件职责 Kibana&#xff1a; 可视化和分析日志数据Elasticsearch&#xff1a; 存储和索引日志数据Logstash&#xff1a; 解析、转换和丰富日志数据Filebeat&#xff1a…

网络系统中安全漏洞扫描为何重要?扫描啥?咋扫描?

在网络系统中&#xff0c;安全漏洞扫描占据着极其重要的位置&#xff0c;这一环节有助于我们发现并消除潜在的安全隐患&#xff0c;进而提高网络安全防护的等级。下面&#xff0c;我将对此进行详尽的说明。 基本概念 漏洞扫描技术可以揭示并评估网站存在的安全风险&#xff0…

Socket 编程 TCP

目录 1. TCP socket API 详解 1.1 socket 1.2 bind 1.3 listen 1.4 accept 1.5 read&&write 1.6 connect 1.7 recv 1.8 send 1.9 popen 1.10 fgets 2. EchoServer 3. 多线程远程命令执行 4. 引入线程池版本翻译 5. 验证TCP - windows作为client访问Linu…

基于TMC5160堵转检测技术的夹紧力控制系统设计与实现

点击下面图片带您领略全新的嵌入式学习路线 &#x1f525;爆款热榜 90万阅读 1.6万收藏 一、技术背景与系统原理 在工业自动化领域&#xff0c;夹紧力控制是精密装配、机床夹具等场景的核心需求。传统方案多采用压力传感器伺服电机的闭环控制方式&#xff0c;但存在系统复杂…

XCTF-web-fileclude

解析如下 <?php include("flag.php"); // 包含敏感文件&#xff08;通常包含CTF挑战的flag&#xff09; highlight_file(__FILE__); // 高亮显示当前PHP文件源代码&#xff08;方便查看代码逻辑&#xff09;if(isset($_GET["file1"]…

OpenShift AI - 启用过时版本的 Notebook 镜像

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.18 OpenShift AI 2.19 的环境中验证 文章目录 查看可用 Notebook 镜像控制台查看命令行查看 Notebook 镜像、Image Stream 和 Image Registry Repository 对应关系启用老版本的 Notebook 镜…

Redis 缓存穿透、缓存击穿、缓存雪崩详解与解决方案

在分布式系统中&#xff0c;Redis 凭借高性能和高并发处理能力&#xff0c;成为常用的缓存组件。然而&#xff0c;在实际应用中&#xff0c;缓存穿透、缓存击穿、缓存雪崩这三大问题会严重影响系统的性能与稳定性。本文将详细解析这三个问题的成因&#xff0c;并提供对应的解决…

DQN和DDQN(进阶版)

来源&#xff1a; *《第五章 深度强化学习 Q网络》.ppt --周炜星、谢文杰 一、前言 Q表格、Q网络与策略函数 Q表格是有限的离散的&#xff0c;而神经网络可以是无限的。 对于动作有限的智能体来说&#xff0c;使用Q网络获得当下状态的对于每个动作的 状态-动作值 。那么 a…

【组件】翻牌器效果

目录 效果组件代码背景素材 效果 组件代码 <template><divclass"card-flop":style"{height: typeof height number ? ${height}px : height,--box-width: typeof boxWidth number ? ${boxWidth}px : boxWidth,--box-height: typeof boxHeight nu…

CentOS 7 环境中部署 LNMP(Linux + Nginx + MySQL 5.7 + PHP)

在 CentOS 7 环境中部署 LNMP&#xff08;Linux Nginx MySQL 5.7 PHP&#xff09; 环境的详细步骤如下。此方案确保各组件版本兼容&#xff0c;并提供完整的配置验证流程。 1. 更新系统 sudo yum update -y 2. 安装 MySQL 5.7 2.1 添加 MySQL 官方 YUM 仓库 由于MySQL并不…

NX811NX816美光颗粒固态NX840NX845

NX811NX816美光颗粒固态NX840NX845 美光NX系列固态硬盘颗粒深度解析&#xff1a;技术、性能与市场全景透视 一、技术架构与核心特性解析 1. NX811/NX816&#xff1a;入门级市场的平衡之选 技术定位&#xff1a;基于176层TLC&#xff08;Triple-Level Cell&#xff09;3D NAN…

捋捋wireshark

本猿搬砖时会用到wireshark分析pcap包&#xff0c;但频率不高&#xff0c;记过一些笔记&#xff0c;今天捋捋&#xff0c;希望能给初学者节省一点时间。 wireshark是个网络封包分析软件&#xff08;network packet analyzer&#xff09;&#xff0c;可以用来抓流量包&#xff…

c++学习之---模版

目录 一、函数模板&#xff1a; 1、基本定义格式&#xff1a; 2、模版函数的优先匹配原则&#xff1a; 二、类模板&#xff1a; 1、基本定义格式&#xff1a; 2、类模版的优先匹配原则&#xff08;有坑哦&#xff09;&#xff1a; 3、缺省值的设置&#xff1a; 4、ty…

第十六章 EMQX黑名单与连接抖动检测

系列文章目录 第一章 总体概述 第二章 在实体机上安装ubuntu 第三章 Windows远程连接ubuntu 第四章 使用Docker安装和运行EMQX 第五章 Docker卸载EMQX 第六章 EMQX客户端MQTTX Desktop的安装与使用 第七章 EMQX客户端MQTTX CLI的安装与使用 第八章 Wireshark工具的安装与使用 …

新编辑器编写指南--给自己的备忘

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…

鸿蒙网络数据传输案例实战

一、案例效果截图 二、案例运用到的知识点 核心知识点 网络连接管理&#xff1a;connection模块HTTP数据请求&#xff1a;http模块RPC数据请求&#xff1a;rcp模块文件管理能力&#xff1a;fileIo模块、fileUri模块 其他知识点 ArkTS 语言基础V2版状态管理&#xff1a;Comp…

【JavaEE】-- 网络原理

文章目录 1. 网络发展史1.1 广域网1.2 局域网 2. 网络通信基础2.1 IP地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 分层的作用2.5.2 OSI七层模型&#xff08;教科书&#xff09;2.5.3 TCP/IP五层&#xff08;或四层&#xff09;模型&#xff08;工业中常用&#xff…