【Hot100】贪心算法

系列文章目录

【Hot100】二分查找


文章目录

  • 系列文章目录
  • 方法论
  • Hot100 之贪心算法
    • 121. 买卖股票的最佳时机
    • 55. 跳跃游戏
    • 45. 跳跃游戏 II
    • 763. 划分字母区间


方法论

Hot100 之贪心算法

121. 买卖股票的最佳时机

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, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:

输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

分析:
        根据数组 prices ,我们可以知道每一天的价格。所以,我们可以再一次遍历中,记录直到当天的历史最低的价格,然后计算当前股价与历史最低的差值,记录每一天的收益情况,最后保留最优值。
答案:

class Solution {
public:int maxProfit(vector<int>& prices) {int minPrice = INT32_MAX, maxProfit = 0;// 遍历每一天,先记录历史最低的价格,再计算当前股价与历史最低的差值,来取出最优值for(int i = 0; i < prices.size(); ++i){minPrice = min(minPrice, prices[i]);    // 先记录历史最低maxProfit = max(maxProfit, prices[i] - minPrice);   // 计算当前股价与历史最低的差值}return maxProfit;}
};

55. 跳跃游戏

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。

示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3步到达最后一个下标。

示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 ,所以永远不可能到达最后一个下标。

分析:
        先看示例 2,nums=[3,2,1,0,4]。我们在遍历数组的同时,维护最右可以到达的位置 mx,如下表:

inums[i]i+nums[i]max
0333
1233
2133
3033
448失败

从 0 可以跳到 1,2,3,但是无法从 1,2,3 中的任何位置跳到 4。
当我们遍历到 i=4 时,发现 i>mxi>mxi>mx,这意味着当前 i 是无法到达的,返回 false

        然后来看示例 1,nums=[2,3,1,1,4],在遍历数组的同时,维护最远可以到达的位置 mx,如下表:

inums[i]i+nums[i]max
0222
1344
2134
3144
4488

    从 0 可以跳到 1,2,最远可以到达的位置 mx=2。
    从 1 可以跳到 2,3,4,mx 更新成 4。
    从 2 可以跳到 3,mx 不变,任为 4。
    从 3 可以跳到 4,mx 不变,任为 4。
    到达 4,返回 true。

一般地,算法如下:
        (1)从左到右遍历 nums,同时维护能跳到的最远位置 mx,初始值为 0
        (2)如果 i>mx,说明无法跳到 i,返回 false
        (3)否则,用 i+nums[i]更新 mx 的最大值。
        (4)如果循环中没有返回 false,那么最后返回 true。


答案:

class Solution {
public:bool canJump(vector<int>& nums) {int mx = 0;for (int i = 0; i < nums.size(); i++) {if (i > mx)  // 无法到达 ireturn false;mx = max(mx, i + nums[i]); // 从 i 最右可以跳到 i + nums[i]}return true;}
};

45. 跳跃游戏 II

45. 跳跃游戏 II:给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。

每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。换句话说,如果你在索引 i 处,你可以跳转到任意 (i + j) 处:

  • 0 <= j <= nums[i] 且
  • i + j < n

返回到达 n - 1 的最小跳跃次数。测试用例保证可以到达 n - 1。

示例 1:
输入: nums = [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:
输入: nums = [2,3,0,1,4]
输出: 2

提示:
    (1) 1 <= nums.length <= 104
    (2) 0 <= nums[i] <= 1000
    (3) 题目保证可以到达 n - 1

分析:
        题目保证可以到达 n - 1,所以问题只要思考最小跳跃数就行。

在这里插入图片描述
        注意:不是在无路可走的那个位置i,使用nums[i]造桥,而是当发现无路可走的时候,时光倒流到能跳到最远点的那个位置造桥。换句话说,在无路可走之前,我们只是在默默地收集信息,没有实际造桥。当发现无路可走的时候,才从收集到的信息中,选择最远点造桥。**因此,维持一个变量,记录下一座要造桥的右端点的最大值。**所建造的这座桥的左端点(起跳位置)在我们当前走的这座桥的中间,而不是桥的末尾。

        答疑,问:为什么代码只需要遍历到 n−2?
        答:代码中的 for 循环计算的是在到达终点之前需要造多少座桥。n−1 已经是终点了,不需要造桥。


答案:

class Solution {
public:int jump(vector<int>& nums) {int ans = 0;int cur_right = 0;  // 已建造的桥的右端点int next_right = 0; // 下一座桥的右端点的最大值for(int i = 0; i < nums.size()-1; ++i){next_right = max(next_right, i+nums[i]);    // 记录下一座桥的最远点if(i == cur_right)  // 无路可走,必须建桥{cur_right = next_right; // 建桥后,最远可以到达 next_rightans ++;}}return ans;}
};

763. 划分字母区间

763. 划分字母区间:给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。例如,字符串 "ababcc" 能够被分为 ["abab", "cc"],但类似 ["aba", "bcc"]["ab", "ab", "cc"] 的划分是非法的。

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

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

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

示例 2:
输入:s = “eccbbbbdec”
输出:[10]

分析:
「同一字母最多出现在一个片段中」意味着,一个片段若要包含字母 a,那么所有的字母 a 都必须在这个片段中。

        例如示例 1,s=ababcbacadefegdehijhklij,其中字母 a 的下标在区间 [0,8] 中,那么包含 a 的片段至少要包含区间 [0,8]

把所有出现在 s 中的字母及其下标区间列出来:

字母下标下标区间
a[0,2,6,8][0,8]
b[1,3,5][1,5]
c[4,7][4,7]
d[9,14][9,14]
e[10,12,15][10,15]
f[11][11,11]
g[13][13,13]
h[16,19][16,19]
i[17,22][17,22]
j[18,23][18,23]
k[20][20,20]
l[21][21,21]

        例如字母 d 的区间为 [9,14],片段要包含 d,必须包含区间 [9,14],但区间 [9,14] 中还有其它字母 e,f,g,所以该片段也必须包含这些字母对应的区间 [10,15],[11,11],[13,13],合并后得到区间 [9,15]

        将表格中的区间合并为如下几个大区间:[0,8],[9,15],[16,23]这些区间满足「同一字母最多出现在一个片段中」的要求。由于题目要求划分出尽量多的片段,而我们又无法将上述区间的任何区间划分开,所以合并出的区间长度即为答案。(本质是合并区间)


答案:

  1. 遍历 s,计算字母 cs 中的最后出现的下标 last[c]
  2. 初始化当前正在合并的区间左右端点 start=0, end=0
  3. 再次遍历 s,由于当前区间必须包含所有 s[i],所以用 last[s[i]] 更新区间右端点 end 的最大值。
  4. 如果发现 end=i,那么当前区间合并完毕,把区间长度 end−start+1 加入答案。然后更新 start=i+1 作为下一个区间的左端点。
  5. 遍历完毕,返回答案。
class Solution {
public:vector<int> partitionLabels(string s) {int n = s.length();int last[26];for (int i = 0; i < n; i++) last[s[i] - 'a'] = i; // 每个字母最后出现的下标vector<int> ans;int start = 0, end = 0;for (int i = 0; i < n; i++) {end = max(end, last[s[i] - 'a']); // 更新当前区间右端点的最大值if (end == i) { // 当前区间合并完毕ans.push_back(end - start + 1); // 区间长度加入答案start = i + 1; // 下一个区间的左端点}}return ans;}
};

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

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

相关文章

电子电气架构 --- 软件项目复杂性的驾驭思路

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

SSE实时通信与前端联调实战

1.SSE 原理机制 sse 类似websocket,但是sse是单向的&#xff0c;不可逆的&#xff0c;只能服务端向客户端发送数据流 2.解决跨域问题 Access to XMLHttpRequest at http://127.0.0.1:8090/sse/doChat from origin http://127.0.0.1:3000 has been blocked by CORS policy: Re…

从传统到创新:用报表插件重塑数据分析平台

一、传统 BI 平台面临的挑战 在当今数字化时代&#xff0c;数据已成为企业决策的重要依据。传统的商业智能&#xff08;BI&#xff09;平台在数据处理和分析方面发挥了重要作用&#xff0c;但随着数据量的爆炸式增长和用户需求的日益多样化&#xff0c;其局限性也逐渐显现。 …

MySQL--MySQL中的DECIMAL 与 Java中的BigDecimal

1. 为什么需要 DECIMAL在数据库中&#xff0c;常见的数值类型有&#xff1a;INT、BIGINT → 整数&#xff0c;存储容量有限。FLOAT、DOUBLE → 浮点数&#xff0c;存储效率高&#xff0c;但存在精度丢失问题。DECIMAL(M, D) → 定点数&#xff0c;存储精确值。例子&#xff1a;…

低空无人机系统关键技术与应用前景:SmartMediaKit视频链路的基石价值

引言&#xff1a;低空经济的新兴格局 低空经济作为“新质生产力”的代表&#xff0c;正在从政策驱动、技术突破和市场需求的共振中走向产业化。2023年&#xff0c;中国低空经济的市场规模已超过 5000 亿元人民币&#xff0c;同比增长超过 30%。无人机&#xff08;UAV&#xff…

在Windows系统上升级Node.js和npm

在Windows系统上升级Node.js和npm&#xff0c;我推荐以下几种方法&#xff1a; 方法1&#xff1a;使用官网安装包&#xff08;最简单&#xff09; 访问 nodejs.org 下载Windows安装包&#xff08;.msi文件&#xff09; 运行安装包&#xff0c;选择"修复"或直接安装新…

【Jetson】基于llama.cpp部署gpt-oss-20b(推理与GUI交互)

前言 本文在jetson设备上使用llama.cpp完成gpt-oss 20b的部署&#xff0c;包括后端推理和GUI的可视化交互。 使用的设备为orin nx 16g&#xff08;super&#xff09;&#xff0c;这个显存大小推理20b的模型完全没有问题。 使用硬件如下&#xff0c;支持开启super模式。&#…

Matplotlib 可视化大师系列(一):plt.plot() - 绘制折线图的利刃

目录Matplotlib 可视化大师系列博客总览Matplotlib 可视化大师系列&#xff08;一&#xff09;&#xff1a;plt.plot() - 绘制折线图的利刃一、 plt.plot() 是什么&#xff1f;二、 函数原型与核心参数核心参数详解三、 从入门到精通&#xff1a;代码示例示例 1&#xff1a;最基…

第二阶段Winfrom-8:特性和反射,加密和解密,单例模式

1_预处理指令 &#xff08;1&#xff09;源代码指定了程序的定义&#xff0c;预处理指令&#xff08;preprocessor directive&#xff09;指示编译器如何处理源代码。例如&#xff0c;在某些情况下&#xff0c;我们希望编译器能够忽略一部分代码&#xff0c;而在其他情况下&am…

【开题答辩全过程】以 微信小程序的医院挂号预约系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

鸿蒙ArkUI 基础篇-06-组件基础语法-Column/Row/Text

目录 掌握组件写法&#xff0c;使用组件布局界面 ArkUI与组件 先布局再内容 DevEco Studio代码实战 预览效果 总结 练习 掌握组件写法&#xff0c;使用组件布局界面 ArkUI与组件 ArkUI&#xff08;方舟开发框架&#xff09;&#xff1a;构建 鸿蒙 应用 界面 的框架 组件…

8.27 网格memo

lc329计算矩阵中最长递增路径长度尝试从矩阵每个位置出发&#xff0c;int dfs() 往上下左右四个方向找严格递增的路径retmax(ret,dfs(x,y)1);return memo[i][j]ret;返回所有路径里的最长长度 class Solution {public:int dx[4]{0,0,1,-1};int dy[4]{1,-1,0,0};int m,n;vector&l…

flume监控文件写入 Kafka 实战:解耦应用与消息队列的最佳实践

flume监控文件写入 Kafka 实战&#xff1a;解耦应用与消息队列的最佳实践 在日志采集场景中&#xff0c;直接让应用程序通过 log4j2 写入 Kafka 会导致应用与 Kafka 强耦合&#xff08;如 Kafka 故障可能影响应用运行&#xff09;。更优的方案是&#xff1a;应用程序将日志写入…

从浏览器无法访问到Docker容器的 FastAPI 服务地址【宿主机浏览器和容器不在同一个网络层面:端口映射】

文章目录1. 问题根源&#xff1a;Docker 网络模型2. 解决方案&#xff1a;端口映射&#xff08;Port Mapping&#xff09;方法 1&#xff1a;重新运行容器并添加端口映射&#xff08;推荐&#xff09;方法 2&#xff1a;获取宿主机的 IP 进行访问&#xff08;特定情况&#xff…

线性代数中矩阵等价与离散数学中关系的闭包之间的关联

最近在重温线性代数时&#xff0c;学到矩阵的等价的定义及其性质&#xff0c;发现其性质与离散数学中关系的闭包所要满足的性质非常相似&#xff0c;不由的让人不怀疑这二者之间存在某种关联&#xff0c;从而引发以下的思考&#xff1a;从deepseek的回答中我明白了矩阵的等价其…

从MyJUnit反思Java项目的工程实践(版本控制篇)

从 MyJUnit 反思Java项目的工程实践(版本控制篇) 参考资料 deepseekgithub copilotCSDN-Git代码管理工作流程&#xff1a;GitFlow详解Conventional Commits手册封面来自 qwen-image 遵循 git flow 分支管理模型 Git Flow 是一种围绕项目发布的核心分支模型, 它规定了不同的开发…

小工具推荐

小工具 ​ 平时不太喜欢去搜罗一些好用的工具&#xff0c;但是看到自己感兴趣的还是会记下来&#xff0c;有的是github上的开源项目&#xff0c;有的是一些直接在线的工具。主要是除了工作时间也不知道去干点什么&#xff0c;或者是和朋友玩玩游戏&#xff0c;或者是city walk…

【js】加密库sha.js 严重漏洞速查

前言sha.js 是 JavaScript 生态里最常用的轻量级加密库。它由 Browserify 社区维护&#xff0c;体积不足 20 KB&#xff0c;却实现了 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 全系列算法&#xff0c;是 crypto-browserify、webpack、web3.js 等数百个流行包的“根依赖”。而…

FPGA入门学习路径

FPGA入门学习路径 专业基础 数电&#xff08;数字电路基础-CSDN博客&#xff09; 语法 Verilog&#xff08;Verilog硬件描述语言-CSDN博客&#xff09; VHDL&#xff08;VHDL硬件描述语言-CSDN博客&#xff09; FPGA开发流程 常用接口设计 学习目的&#xff1a;通过简单…

HTML响应式设计的颜色选择器,适配各种屏幕尺寸

颜色选择器 响应式设计的颜色选择器&#xff0c;适配各种屏幕尺寸 支持色相滑块和RGB数值两种调色方式 点击颜色值或复制按钮即可复制十六进制颜色代码 自动根据背景色调整文字颜色确保可读性 包含复制成功提示动画效果 现代化UI设计&#xff0c;采用圆角、阴影和渐变背景 完全…