news 2026/5/1 7:17:28

贪心算法专题(十三):画地为牢的艺术——「划分字母区间」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
贪心算法专题(十三):画地为牢的艺术——「划分字母区间」

哈喽各位,我是前端小L。

欢迎来到贪心算法专题第十三篇! 题目给你一个字符串,让你把它切成尽可能多的片段。硬性要求同一个字母只能出现在一个片段里。 这意味着:如果第一段里有了 'a',那么字符串里剩下的所有 'a' 都必须被关在第一段里,决不能跑出去。

力扣 763. 划分字母区间

https://leetcode.cn/problems/partition-labels/

题目分析:

  • 输入:字符串s

  • 输出:一个数组,包含每个片段的长度。

例子:s = "ababcbacadefegdehijhklij"

  • 我们看第一个字母a。它最后一次出现在下标8

  • 这意味着:第一段的结束位置,至少要是8

  • 但还没完!在08之间,我们还发现了bb最后一次出现在下标5(在8以内,没事)。

  • 我们还发现了cc最后一次出现在下标7(在8以内,没事)。

  • 所以,第一段就可以在下标8处切断。长度为9("ababcbaca")。

  • 接下来看d...

核心思维:寻找“最远边界”

贪心策略非常直观:对于当前片段里的每一个字母,我都要确保它的“最后一次出现位置”在这个片段内。

这意味着,当前片段的结束边界 (end),是由片段内所有字母的最后出现位置的最大值决定的。

步骤拆解:

  1. 预处理:我们需要知道每个字母“最后在哪里出现”。遍历一遍字符串,用一个哈希表(或数组)记录下来。

    • 例如:map['a'] = 8,map['b'] = 5...

  2. 贪心遍历

    • 维护两个变量:start(当前片段起点),end(当前片段的最远边界)。

    • 遍历字符串:

      • 对于当前字符c,更新end = Math.max(end, map[c])

      • 关键判断:如果当前下标i走到了end,说明什么?

      • 说明在这个范围内出现的所有字母,它们的最后出现位置都在这里面了!再往后走就是全新的字母了。

      • 切断!记录长度end - start + 1

      • 更新下一段的起点start = i + 1

算法流程 (JavaScript)

  1. 统计最远位置

    • 创建一个对象或数组lastIndex

    • 遍历slastIndex[s[i]] = i

  2. 双指针遍历

    • start = 0,end = 0

    • 遍历s(索引i):

      • end = Math.max(end, lastIndex[s[i]])

      • 如果i === end

        • 收集结果:result.push(end - start + 1)

        • 重置起点:start = i + 1

代码实现

JavaScript

/** * @param {string} s * @return {number[]} */ var partitionLabels = function(s) { // 1. 记录每个字符最后出现的位置 // 用对象或者大小为26的数组都可以 const lastIndex = {}; for (let i = 0; i < s.length; i++) { lastIndex[s[i]] = i; } const result = []; let start = 0; // 当前片段的起始位置 let end = 0; // 当前片段的最远结束位置 // 2. 再次遍历,寻找切割点 for (let i = 0; i < s.length; i++) { // 贪心:不断扩展当前片段的边界 // 只要当前字符的最后出现位置比 end 大,就把 end 撑大 end = Math.max(end, lastIndex[s[i]]); // 如果遍历到了边界,说明这一段可以切了 if (i === end) { result.push(end - start + 1); // 记录长度 start = i + 1; // 准备开始下一段 } } return result; };

深度图解

假设s = "abc...a..."(a 最后在 10)

  1. i=0, char='a'。end变成 10。目前片段至少要到 10。

  2. i=1, char='b'。假如 'b' 最后在 5。max(10, 5)还是 10。没事。

  3. ...

  4. 假如中间有个 'e' 最后在 15。那end瞬间被撑大到 15。片段必须延长!

  5. i终于追上了end(比如走到 15 了),说明前面所有人的要求都满足了。切!

复杂度分析

  • 时间复杂度:O(N)

    • 第一遍遍历统计位置 O(N)。

    • 第二遍遍历寻找切割点 O(N)。

    • 总共 O(N)。

  • 空间复杂度:O(1)

    • 虽然用了哈希表,但字符集大小固定是 26 个小写字母,所以空间是常数级的。

总结:边界的动态扩张

这道题展示了贪心算法处理**“动态约束”的能力。 最开始约束很小(只看第一个字母),随着遍历的进行,新加入的字母可能会“撑大”**这个约束(更新end)。我们只能顺从这个约束,直到我们走到了约束的尽头。


下一题预告:合并区间

接下来这道题LC 56. 合并区间,是区间问题的终极模板,也是面试中出现频率最高的题目之一(Top 3 级别)。

  • 给你一堆乱序的区间[1,3], [8,10], [2,6], [15,18]

  • 让你把重叠的区间全部合并成一个大区间。

  • 比如[1,3][2,6]重叠,合并成[1,6]

这道题和我们之前的“无重叠区间”逻辑正好相反,但操作手法(排序+更新边界)依然是熟悉的味道。

准备好进行最后的区间大一统了吗?下期见!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 15:42:20

CMP-C9-Azido-sialic Acid — 糖合成与生物偶联的关键修饰糖核苷酸

CMP-C9-Azido-sialic Acid 是一种经过化学修饰的糖核苷酸&#xff0c;属于Sugar Nucleotides类别。它在糖生物学、药物开发和诊断研究领域具有重要价值&#xff0c;通过引入叠氮基团&#xff0c;为糖链的精准修饰和功能化提供了强大工具。这种分子不仅扩展了糖科学的研究边界&a…

作者头像 李华
网站建设 2026/4/26 22:19:02

深度测评9个AI论文工具,助研究生高效完成论文写作!

深度测评9个AI论文工具&#xff0c;助研究生高效完成论文写作&#xff01; AI 工具如何改变论文写作的未来 在当今信息爆炸的时代&#xff0c;研究生们面临着前所未有的学术挑战。无论是撰写开题报告、完成实验分析&#xff0c;还是最终的论文定稿&#xff0c;每一个环节都需要…

作者头像 李华
网站建设 2026/4/19 14:06:40

AI Coding在嵌入式开发中的应用

文章由来最近在测试各种AI Coding工具&#xff0c;通常以python 小项目作为测试内容。发现现在的AI coding工具越来越智能了。以后的工程师将面临两极分化&#xff0c;小白级&#xff08;只会用AI写代码&#xff09;&#xff0c;大神级&#xff08;优化AI的前沿工程师&#xff…

作者头像 李华
网站建设 2026/4/29 9:34:31

2025 博客成长复盘:我的博客生涯迎来深度质变

当2025年的日历翻到最后一页&#xff0c;我点开CSDN的年度创作总结页面时&#xff0c;屏幕上跳出的“2017年03月07日&#xff0c;我们和你第一次相遇”突然撞进眼里——原来从注册CSDN账号到成为一名持续输出的博主&#xff0c;已经走过了近9个年头。而2025这一年&#xff0c;3…

作者头像 李华
网站建设 2026/4/27 23:52:09

Eclipse 工作空间:深入解析与高效使用指南

Eclipse 工作空间:深入解析与高效使用指南 引言 Eclipse,作为一款功能强大的集成开发环境(IDE),在Java开发领域有着举足轻重的地位。本文将深入解析Eclipse工作空间的概念、配置方法以及高效使用技巧,帮助开发者更好地掌握这一开发工具。 一、Eclipse工作空间概述 1.…

作者头像 李华
网站建设 2026/4/23 17:19:42

ZWPD 开放生态:打通设计 - 施工 - 交付 - 运维的工业数据链路

流程工业数字化转型中&#xff0c;数据是核心资产&#xff0c;但设计、施工、交付、运维四阶段长期存在“数据孤岛”&#xff0c;导致项目周期长、成本高、效率低&#xff0c;数字化交付质量难以保障。国产三维工厂设计平台中维ZWPD以“开放生态”为核心战略&#xff0c;通过接…

作者头像 李华