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

HOT100题打卡第37天——贪心算法

贪心算法

贪心算法是解决优化问题的核心思路之一。核心结论是:贪心算法通过每一步都做出局部最优选择,最终希望得到全局最优解,但并非适用于所有问题。

核心特点

  1. 局部最优优先:每一步都选择当前情况下的最优解,不回溯。
  2. 无后效性:当前选择只依赖当前状态,不影响后续状态的选择逻辑。
  3. 适用场景有限:仅当问题满足 “贪心选择性质” 和 “最优子结构性质” 时,才能得到全局最优。

适用问题与经典案例

  • 贪心选择性质:全局最优解可通过一系列局部最优解逐步构造。
  • 最优子结构:问题的最优解包含其子问题的最优解。
  • 经典案例:
    • 哈夫曼编码:通过每次合并权重最小的节点,得到最优编码方案。
    • 活动选择问题:每次选择结束时间最早的活动,最大化可参与活动数。
    • 零钱兑换(特定面额):如美元硬币体系,每次选最大面额,可快速找零。

局限性

  • 并非万能:很多问题中局部最优无法累积成全局最优,比如普通零钱兑换问题(如面额 1、3、4,兑换 6 元,贪心选 4+1+1=6,最优为 3+3=2 枚)。
  • 需严格验证:使用前必须证明问题满足两大性质,否则可能得到次优解。

例题

121. 买卖股票的最佳时机

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

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

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

示例 1:

输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

分析题目

这道题需要结合动态规划和贪心算法的知识来解决

要求最大利润,需要求出每一天卖出股票获得的最大利润,然后取最大值

dp数组的含义

用一个数组来储存每一天卖出股票能获取的最大利润,下标 i 就表示第 i 天,dp[ i ]就表示若当天卖出股票能获取的最大利润,因此dp数组的长度=price数组长度+1,索引0位置表示第0天卖出股票获取到的最大利润,即0,后面的索引 i 就和天数一一对应

数组初始化

为了不影响结果,数组中所有位置都默认初始值为0,即股票未卖出状态

因为只能不能在买入的同天卖出,所以第一天只能买入不能卖出,dp[ 1 ]=0

循环遍历

因为只能先买入再卖出,所以倒序遍历数组,遍历到的索引位置就表示卖出当天,往当前索引之前遍历买入股票的日子,得到当日卖出股票的最大利润存入dp数组,最后求dp数组的最大值就得到了最大利润


代码

import java.util.Arrays;class Solution {public int maxProfit(int[] prices) {int[] dp = new int[prices.length+1];for (int i = dp.length-1; i >= 2; i--) {int profit = 0;for (int j = 1; j < i; j++) {int currentProfit=prices[i-1]-prices[j-1];profit=Math.max(profit,currentProfit);}dp[i]=profit;}int maxProfit=0;for (int i = 0; i < dp.length; i++) {maxProfit=Math.max(maxProfit,dp[i]);}return maxProfit;}
}

这个算法的时间复杂度是 O (n²),可以解决大多数用例,但数组长度过长还是会超时,而且dp数组其实没有起到什么作用,直接用一个变量不变更新就可以,看看下面这个算法


class Solution {public int maxProfit(int[] prices) {
//这个变量用来储存最大利润int maxProfit = 0;//这个变量储存的是我们遇到的所有元素中的最大值,初始把数组末尾的数作为当前我们遇到的最大值int maxPrice=prices[prices.length-1];
//还是倒序遍历数组,从倒数第二天开始,如果当天的股票价格小于这天之后的股票最高价,也就是maxProfit
//就可以计算出当前的利润,通过这种方式向前遍历不断更新利润的最大值for (int i = prices.length - 2; i >= 0; i--) {if(prices[i]<maxPrice){int profit=maxPrice-prices[i];maxProfit=Math.max(maxProfit,profit);}
//如果当天股票价格大于后来的最大值,那就把股价最大值更新为当前值,继续向前遍历if(prices[i]>maxPrice){maxPrice=prices[i];}}
//最后将最大值返回return maxProfit;}
}

这样就可以把时间复杂度降低到O(n),空间复杂度降低到O(1),大大提升了效率

http://www.dtcms.com/a/601121.html

相关文章:

  • Python学习历程——模块
  • bin文件反编译C语言 | 深入探讨反编译技术及其应用
  • 测开学习DAY27
  • dede cms 网站模板云匠网怎么样
  • 信息学奥赛一本通 1625:【例 1】反素数 Antiprime | 洛谷 P1463 [POI 2001 R1 / HAOI2007] 反素数
  • 如何做网站长尾关键词布局工程公司取名字大全
  • 深度学习:从零开始手搓一个深层神经网络
  • Docker 多服务镜像构建完整教程
  • Docker 启动 EMQX 5.x 并配置自签名证书
  • 网站招工费怎么做会计分录小小视频免费观看高清
  • C++重点知识梳理(上)
  • 长沙市建设局官方网站wordpress 显示文章标签
  • 基于用户评论分析挖掘的旅游景点推荐系统
  • 宣传旅游网站建设的重点是什么装修公司哪家好排名
  • 【C语言学习笔记】动态内存分配:malloc/free的正确打开方式
  • HOVER:用于人形机器人的多功能全身神经控制器
  • 学会给网页穿衣服——学习 CSS 语言
  • Android11-Launcher3 定制-去除副屏幕-可以滑动效果 - 篇二
  • 在 ubuntu怎么创建一个新用户,并且设置为默认自动登录用户,最简单
  • 字符串的陷阱与艺术——std::string全解析
  • 深信服云桌面有什么替代方案?
  • 网页制作与网站建设试卷及答案wordpress 默认文章形式
  • 企业为什么要建立自己的网站云南工程建设信息网站
  • Dubbo如何使用Nacos做注册中心的
  • 决策树悲观错误剪枝(PEP)详解:原理、实现与应用
  • 外卖项目 day01
  • 前端vue3 window.open 项目部署后页面404解决办法
  • pc网站 手机网站 微信网站 上海跨境电商官方网站建设
  • Windows 10 C语言编译器安装与配置
  • 网站后台进不去的原因挂机宝做php网站吗