从零开始写算法——贪心篇2:买卖股票的最佳时间 + 划分字母区间
在算法中贪心算法 (Greedy Algorithm)往往是一个让人又爱又恨的话题。爱它是因为代码通常很短恨它是因为“当前最优选择会导致全局最优”这个逻辑有时候很难一眼看穿。今天我们通过两道经典的 LeetCode 题目——121. 买卖股票的最佳时机和763. 划分字母区间来感受一下贪心算法如何在“一次遍历”中解决问题。这两个题目虽然场景完全不同但核心思想是通用的维护一个关键的状态变量最小值或最远边界在遍历过程中不断更新这个状态从而得到最终答案。Part 1买卖股票的最佳时机 —— 维护“历史最低点”1. 题目核心给定一个数组prices它的第i个元素是一支给定股票第i天的价格。如果你最多只允许完成一笔交易即买入和卖出一支股票一次设计一个算法来计算你所能获取的最大利润。2. 贪心策略我们要赚钱核心逻辑非常简单“低买高卖”。 但是我们不能穿越时空我们只能在当前这一天决定如果在今天卖出我能赚多少取决于之前的最低价是多少。今天是不是一个新的“历史最低点”如果是那以后如果想买肯定按今天的价格买更划算。所以我们需要维护一个变量min_price代表过去几天包括今天出现的最低股价。3. 代码实现 (C)你的代码中有一个非常有意思的注释关于“先算利润还是先更新最小值”的讨论这体现了很好的思考深度。C代码实现class Solution { public: int maxProfit(vectorint prices) { // 思路就是我们通过一次遍历但是这个遍历中我们去维护最小值以及更新答案 // min_price 初始化为第一天的价格 int ans 0, min_price prices[0]; for (int x : prices) { /* 这里有一个细节逻辑 我们是先计算 ans max(ans, x - min_price)再更新 min_price。 这意味着我们计算的是【今天的价格 - 之前几天的最低价】。 如果你反过来先更新 min_price再算 ans 那么计算的就是【今天的价格 - 包括今天在内的历史最低价】。 如果今天就是最低价利润算出来是 0反正 ans 初始化也是 0 所以这两种写法对最终结果 ans 没有影响。 */ ans max(ans, x - min_price); min_price min(min_price, x); } return ans; } };4. 复杂度分析时间复杂度O(N)我们只用了一个for循环遍历数组prices每个元素只访问了一次。空间复杂度O(1)我们只使用了ans和min_price两个整数变量不需要额外的数组空间。Part 2划分字母区间 —— 维护“最远边界”1. 题目核心给你一个字符串s。我们要把这个字符串划分为尽可能多的片段同一字母最多出现在一个片段中。 例如ababcbacadefegdehijhklij。a出现在最前面也出现在下标 8 的位置。那么第一个片段至少要切在下标 8 之后否则a就跨越两个片段了。2. 贪心策略这道题的贪心逻辑在于一旦由于某个字母比如 a被迫扩大了区间这个区间内的所有其他字母比如 b, c也得被包进来。我们可以把这个问题分解为两个步骤预处理每个人都想知道自己“最后出现的位置”在哪里。我们可以先遍历一遍记下每个字母最后一次出现的下标。合并区间我们维护一个end指针表示当前片段至少要延伸到的位置。当我们遍历到一个字符c时看看它的最后出现位置是不是比当前的end还远如果是为了包住这个c我们的片段必须延长end变大。何时收网当遍历下标i追上了end时说明这一段里所有出现过的字母它们的最后一次出现位置都在i之前或就是i。此刻我们可以安全地切一刀3. 代码实现 (C)这一段代码完美诠释了“二次遍历”的思想。C代码实现class Solution { // 思路 同一个字母最多出现在一个片段中意味这个区间要包含所有这个字母所以需要对区间进行划分 // 先计算每个字母对应下标然后划分出区间然而区间内的其他字母也会有自己对应的区间此时应该进行合并区间 // 也就是我们目标两次遍历第一次预处理第二次进行划分。 public: vectorint partitionLabels(string s) { int n s.size(); // last 数组用来充当哈希表记录每个字符最后出现的下标 // 大小为 26对应 a-z int last[26]; for (int i 0; i n; i) { last[s[i] - a] i; // 不断更新最后留下的就是最后一次出现的下标 } vectorint ans; int start 0, end 0; // 第二次遍历根据最远边界进行切割 for (int i 0; i n; i) { // 贪心核心end 必须能包住当前字符 s[i] 的最后出现位置 end max(end, last[s[i] - a]); // 如果当前的遍历下标 i 追上了 end说明当前片段可以结束了 if(end i) { ans.push_back(end - start 1); // 计算当前片段长度 start i 1; // 更新下一个片段的起点 } } return ans; } };4. 复杂度分析时间复杂度O(N)虽然有两个for循环但它们是并列的不是嵌套的。第一个循环遍历N次构建last数组。第二个循环遍历N次进行切割。总操作次数是2N在渐进复杂度中依然是 O(N)。空间复杂度O(1)虽然我们开辟了一个last数组但它的大小固定为 26字符集大小不随字符串长度N变化。在算法分析中常数大小的空间视为 O(1)。注返回值的ans数组通常不计入算法的空间复杂度因为它用于存储结果。总结这两道题虽然外表不同但本质上都是线性扫描 状态更新买卖股票我们在扫描中更新最小值 (min)一旦遇到高价就计算利润。划分字母我们在扫描中更新最远边界 (end)一旦到达边界就进行切割。这种“走一步看一步”且只需一次或两次遍历的方法正是贪心算法在处理线性数据结构时的强大之处。掌握这种思维能让你在面试中快速写出 O(N) 的高效代码。

相关新闻

毕业设计 基于单片机的红外热视仪(源码+硬件+论文)

毕业设计 基于单片机的红外热视仪(源码+硬件+论文)

文章目录 0 前言1 主要功能2 硬件设计3 核心软件设计4 实现效果5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己…

2026/5/17 3:26:43 阅读更多 →
2026 AI写论文软件大比拼:学生党适配指南

2026 AI写论文软件大比拼:学生党适配指南

PaperRed(全流程全能降重王者)与毕业之家(毕业全流程专属查重适配)是学生党首选;本科生优先PaperRed免费版按次付费,研究生选PaperRed标准版或毕业之家专业版,预算有限可搭配ChatGPT免费版辅助构…

2026/7/5 2:28:27 阅读更多 →
C语言对话-31.与大虾对话 领悟设计模式

C语言对话-31.与大虾对话 领悟设计模式

myan(孟岩) 翻译 [译者按] 本文根据发表在CUJ Expert Forum上的两篇文章编译而成。C/C Users Journal是目前最出色的C/C语言专业杂志,特别是在C Report闭刊之后,CUJ的地位更加突出。CUJ Expert Forum是CUJ主办的网上技术专栏,汇集2000年10月以…

2026/5/17 3:26:43 阅读更多 →

最新新闻

热红外视觉下的车辆/船舶重识别新方法:Vc-fes

热红外视觉下的车辆/船舶重识别新方法:Vc-fes

在监控与海事安防等场景中,如何在**热红外图像**(灰度、无色彩、纹理弱)中准确识别同一辆车或同一艘船,是一个长期悬而未决的难题。近期发表于《International Journal of Machine Learning and Cybernetics》(2026年)的论文《Vc-fes: viewpoint-conditioned feature selection…

2026/7/5 9:10:34 阅读更多 →
本地AI完全指南①:我把ChatGPT退了,一年省2400——为什么越来越多人把大模型搬回家

本地AI完全指南①:我把ChatGPT退了,一年省2400——为什么越来越多人把大模型搬回家

title: 本地AI完全指南①:我把ChatGPT退了,一年省2400——为什么越来越多人把大模型搬回家? tags: 本地AI,私有大模型,Ollama,DeepSeek,大模型部署,AI隐私,离线AI,本地部署大模型,DeepSeek本地部署 category: 人工智能 本地AI完全指南①&…

2026/7/5 9:10:34 阅读更多 →
同一个模型,三个平台:OpenRouter - SiliconFlow - DeepInfra 实测对比

同一个模型,三个平台:OpenRouter - SiliconFlow - DeepInfra 实测对比

前面几期测的都是模型官方 API。但你实际用的时候,大概率走的不是官方——而是通过某个聚合平台。 为什么?几个现实原因: 不想每个模型绑一张信用卡公司采购要求统一结算官方 API 在某些地区不稳定想用一个 API Key 调所有模型 所以这期我不测…

2026/7/5 9:10:34 阅读更多 →
GRPO训练燃料:把Hermes Agent Feedback变成强化学习信号

GRPO训练燃料:把Hermes Agent Feedback变成强化学习信号

GRPO训练燃料:把Agent Feedback变成强化学习信号 「Hermes Agent自进化智能体深度解析」系列 | 模块十六 第3篇 你的Agent积累了1000条执行轨迹。500条成功,500条失败。成功的路径有的快、有的慢,失败的失败方式各不相同。你盯着这些数据&a…

2026/7/5 9:08:34 阅读更多 →
艾尔登法环mod下载法魂Modv3.0安装指南

艾尔登法环mod下载法魂Modv3.0安装指南

法魂Mod是一款热度突破680万、持续更新超过三年的《艾尔登法环》大型大修模组。3.0版本带来了全新宝珠系统、大量原创武器与法术、DLC区域地图重置等重大更新,并兼容无缝联机与光荣商人等主流功能性模组。以下为完整安装流程与多Mod共存配置方法。 版本核心更新内容…

2026/7/5 9:08:34 阅读更多 →
x64dbg:Windows 逆向分析的开源调试器

x64dbg:Windows 逆向分析的开源调试器

文章目录x64dbg:Windows 逆向分析的开源调试器它能干什么为什么逆向圈都在用1. 填补了工具断层2. 插件生态起来了3. 真正的开源底层技术栈实际体验我的建议x64dbg:Windows 逆向分析的开源调试器 搞逆向工程的人都知道,调试器是吃饭的家伙。I…

2026/7/5 9:06:34 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻