【贪心算法】——力扣763. 划分字母区间

763. 划分字母区间

一、题目难度

中等

二、相关标签与相关企业

[相关标签]
[相关企业]

三、题目描述

给你一个字符串 s。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。

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

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

四、示例

示例1

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

示例2

输入s = "eccbbbbdec"
输出[10]

五、提示

  1. 1 <= s.length <= 500
  2. s 仅由小写英文字母组成

贪心算法

  • 思路:
    • 首先,我们先遍历一次字符串,用字典last_s = { }记录每个字母最后出现的位置。
    • 然后,我们再次从头遍历字符串,设定一个当前片段起startend位置,后续不断更新维护该片段。
      • startend都初始化为0
      • 遍历过程中,对于每个字符,更新end为当前字符最后出现位置的最大字符
      • 当遍历到i位置等于end时,说明当前片段已经包含了所有出现过的字母
      • 当前片段的长度end - start +1添加到结果列表中
      • 更新starti + 1,开始下一个片段的划分

——————————————————————————————————————————————
如何实现用字典enumerate()函数记录最后出现的位置??

1. enumerate函数**

  • 功能:
    • enumerate 是 Python 中的一个内置函数,它用于在遍历可迭代对象(如列表、字符串等)时,同时返回元素的索引和元素本身。它的基本语法是 enumerate(iterable, start=0),其中iterable是要遍历的可迭代对象,start 是可选参数,用于指定索引的起始值,默认是 0
  • 用法:
    • 当执行for i, char in enumerate(s): 时,对于字符串 s 中的每个字符chari,enumerate 会依次获取到该字符在字符串中的索引(从 0 开始,因为默认 start=0),而 char 则获取到对应的字符本身。例如,如果 s = "abc",那么第一次循环时,i 会是 0char 会是 a;第二次循环时,i 会是 1char 会是 b;第三次循环时,i 会是 2char 会是 c

以下是对这段代码中字典 last_index 以及 enumerate 函数相关操作的详细解释:

2. 字典 last_index

  • 注意字典写入方法

    • last_index={} # 创建字典
    • last_index[a] = 1 # 写入键值对
    • ——>
    • last_index = {'a' : 1}
  • 功能及初始化

    • 字典是Python中的一种数据结构,它以键值对的形式存储数据,其中键是唯一的,通过键可以快速访问到对应的 值。在这里,last_index 字典被初始化为一个空字典 {},它的作用是用于记录每个字母在字符串 s 中最后出现的位置。
  • 记录最后出现位置的原理

    • 在循环 for i, char in enumerate(s): 中,每次遍历到一个字符 char 时,我们就将这个字符作为键,将它当前的索引 i 作为值,存入 last_index 字典中。关键在于,由于我们是按照字符串的顺序依次遍历的,所以当遇到同一个字母多次出现时,后面出现的位置索引会覆盖前面的记录。这样,当整个字符串遍历完成后,字典 last_index 中每个字母对应的键值对中,值就是该字母在字符串中最后出现的位置。
  • 写入后字典的形式示例

    • 假设字符串 s = "ababcbacadefegdehijhklij",经过上述循环遍历后,last_index 字典的形式可能如下:
{'a': 8,'b': 5,'c': 7,'d': 14,'e': 15,'f': 11,'g': 13,'h': 19,'i': 22,'j': 23,'k': 20,'l': 21
}

可以看到,每个字母作为键,其最后出现的位置作为值被准确地记录在了字典中。这样,在后续处理划分字母区间的过程中,我们就可以方便地通过查询这个字典来获取每个字母的最后出现位置信息,以便确定每个片段的范围。

class Solution:def partitionLabels(self, s: str) -> List[int]:# 1. 统计每个字符最后出现的位置(用到enumerate迭代器,返回字符串的索引和字符)# 初始化字典last_indexlast_index = {}# 从头遍历每个字符char出现的位置,由于从头向后遍历,后面的位置会覆盖前面的,for i, char in enumerate(s):last_index[char] = i# 2. 从头遍历字符串s的字符char,# 初始化起末位置start = 0end = 0# 初始化结果列表res = []# 再次遍历,对于每个字符char,索引ifor i, char in enumerate(s):# 更新end,为当前字符char最后出现的位置(字典中存着)end = last_index[char]if i == end:res.append(end- start + 1)return res
————————————————————————————————————————————
执行出错
0 / 118 个通过的测试用例
IndentationError: unindent does not match any outer indentation level^start = 0
Line 12  (Solution.py)

以上代码错误,是我顺着之前的算法步骤写的!
问题出在哪?
太粗心了呀!!!

  • 首先,i碰到一次end,需要更新start位置为i+1
    if i == end:res.append(end- start + 1)start = i + 1

一个很关键的点,下面来详细解释一下为什么是 end = max(end, last_index[char]) 而不是直接 end = last_index[char]

理解需求

我们的目标是划分字符串 s 为尽可能多的片段,使得同一字母最多出现在一个片段中。在遍历字符串的过程中,要确定每个片段的结束位置 end,这个位置应该是当前片段内所有字母最后可能出现的最远位置。

直接赋值的问题(end = last_index[char]

如果按照 end = last_index[char] 来更新 end,那么每次遇到一个字符 char,就会直接将 end 设置为该字符在字典中记录的最后出现位置。这样做会导致一个问题,就是可能会把 end 的值设置得过小,无法包含当前片段内其他字母后续可能出现的位置。

例如,对于字符串 s = "ababcbacadefegdehijhklij",假设我们已经开始划分第一个片段,初始时 end = 0。当我们遍历到字符 a 时,如果按照直接赋值的方式,end 就会被设置为 a 的最后出现位置,也就是 8。但此时,在后续的字符串中,还有其他字母(如 bc 等)在这个片段内也会出现,并且它们的最后出现位置可能比 8 更远。如果就这样把 end 固定为 8,那么就无法正确划分出满足条件的片段,可能会导致某些字母被错误地划分到了下一个片段中,违背了“同一字母最多出现在一个片段中”的要求

取最大值的好处(end = max(end, last_index[char])

而使用 end = max(end, last_index[char]) 来更新 end,就可以避免上述问题。每次遇到一个字符 char,我们会比较当前的 end 值和该字符 char 的最后出现位置(last_index[char])。

  • 如果 last_index[char] 大于当前 end 值,说明该字符的最后出现位置更远,那么就需要把 end 更新为这个更远的位置,以确保 end 能够包含该字符以及可能后续出现的其他字母的最远位置。
  • 如果 last_index[char] 小于等于当前 end 值,说明当前 end 的值已经能够涵盖该字符后续可能出现的位置了,不需要对 end 进行更新。

继续以上面的字符串为例,初始时 end = 0,当遍历到字符 a 时,假设 a 的最后出现位置是 8,此时 end = max(0, 8)end 就会被更新为 8。接着当遍历到字符 b 时,假设 b 的最后出现位置是 5,因为 5 小于当前的 end(也就是 8),所以 end 保持不变,还是 8。但当遍历到字符 c 时,假设 c 的最后出现位置是 7,此时 end = max(8, 7)end 依然保持为 8。这样,通过不断地取最大值来更新 end,就能保证 end 始终是当前片段内所有字母最后可能出现的最远位置,从而正确地划分出满足条件的片段。

所以,不能简单地为每一个 char 都直接赋予 end,而是要通过取最大值的方式来更新 end,以确保划分片段的正确性。

修改了代码:

class Solution:def partitionLabels(self, s: str) -> List[int]:# 1. 统计每个字符最后出现的位置(用到enumerate迭代器,返回字符串的索引和字符)# 初始化字典last_indexlast_index = {}# 从头遍历每个字符char出现的位置,由于从头向后遍历,后面的位置会覆盖前面的,for i, char in enumerate(s):last_index[char] = i# 2. 从头遍历字符串s的字符char,# 初始化起末位置start = 0end = 0# 初始化结果列表res = []# 再次遍历,对于每个字符char,索引ifor i, char in enumerate(s):# 更新end,为当前字符char最后出现的位置(字典中存着)# 错:end = last_index[char]# 改:end = max(last_index[char], end)if i == end:res.append(end- start + 1)# 错,加:start = i + 1 return res
————————————————————————————————————————————————————————
IndentationError: unindent does not match any outer indentation level^start = 0
Line 12  (Solution.py)

检查半天原来是缩进问题,缩进是python的特色。

class Solution:def partitionLabels(self, s: str) -> List[int]:# 1. 统计每个字符最后出现的位置(用到enumerate迭代器,返回字符串的索引和字符)# 初始化字典last_indexlast_index = {}# 从头遍历每个字符char出现的位置,由于从头向后遍历,后面的位置会覆盖前面的,for i, char in enumerate(s):last_index[char] = i# 2. 从头遍历字符串s的字符char,# 初始化起末位置start = 0end = 0# 初始化结果列表res = []# 再次遍历,对于每个字符char,索引ifor i, char in enumerate(s):# 更新end,为当前字符char最后出现的位置(字典中存着)# 错:end = last_index[char]# 改:end = max(last_index[char], end)if i == end:res.append(end- start + 1)# 错,加:start = i + 1 return res
————————————————————————————
通过

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

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

相关文章

【深度学习】LSTM、BiLSTM详解

文章目录 1. LSTM简介&#xff1a;2. LSTM结构图&#xff1a;3. 单层LSTM详解4. 双层LSTM详解5. BiLSTM6. Pytorch实现LSTM示例7. nn.LSTM参数详解 1. LSTM简介&#xff1a; LSTM是一种循环神经网络&#xff0c;它可以处理和预测时间序列中间隔和延迟相对较长的重要事件。LSTM通…

使用ookii-dialogs-wpf在WPF选择文件夹时能输入路径

在进行WPF开发时&#xff0c;System.Windows.Forms.FolderBrowserDialog的选择文件夹功能不支持输入路径&#xff1a; 希望能够获得下图所示的选择文件夹功能&#xff1a; 于是&#xff0c;通过NuGet中安装Ookii.Dialogs.Wpf包&#xff0c;并创建一个简单的工具类&#xff1a; …

【leetcode练习·二叉树】用「分解问题」思维解题 II

本文参考labuladong算法笔记[【强化练习】用「分解问题」思维解题 II | labuladong 的算法笔记] 技巧一 类似于判断镜像二叉树、翻转二叉树的问题&#xff0c;一般也可以用分解问题的思路&#xff0c;无非就是把整棵树的问题&#xff08;原问题&#xff09;分解成子树之间的问…

Qt 编写插件plugin,支持接口定义信号

https://blog.csdn.net/u014213012/article/details/122434193?spm1001.2014.3001.5506 本教程基于该链接的内容进行升级&#xff0c;在编写插件的基础上&#xff0c;支持接口类定义信号。 环境&#xff1a;Qt5.12.12 MSVC2017 一、创建项目 新建一个子项目便于程序管理【…

PaaS云原生:分布式集群中如何构建自动化压测工具

场景 测试环境中&#xff0c;压测常常依赖环境中的各种工具获取基础信息&#xff0c;而这些工具可能集中在某个中控机上&#xff0c;此时想打造的自动化工具的运行模式是&#xff1a; 通过中控机工具获取压测所需的基本信息在中控机部署压测工具&#xff0c;实际压测任务分发…

关于sass在Vue3中编写bem框架报错以及警告问题记录

在编写完bem框架后 在vite.config.ts文件进行预编译处理时&#xff0c;报错的错误 1. 处理方式&#xff1a;使用新版api&#xff0c; 如图&#xff1a; 2. 处理方式&#xff1a;使用 use 替换掉 import&#xff0c; 如图&#xff1a; 3. 处理方式&#xff1a;使用路径别名&am…

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪

内置RTK北斗高精度定位的4G执法记录仪、国网供电服务器记录仪BD311R 发布时间: 2024-10-23 11:28:42 一、 产品图片&#xff1a; 二、 产品特性&#xff1a; 4G性能&#xff1a;支持2K超高清图传&#xff0c;数据传输不掉帧&#xff0c;更稳定。 独立北…

【前端】深入浅出的React.js详解

React 是一个用于构建用户界面的 JavaScript 库&#xff0c;由 Facebook 开发并维护。随着 React 的不断演进&#xff0c;官方文档也在不断更新和完善。本文将详细解读最新的 React 官方文档&#xff0c;涵盖核心概念、新特性、最佳实践等内容&#xff0c;帮助开发者更好地理解…

【Elasticsearch入门到落地】1、初识Elasticsearch

一、什么是Elasticsearch Elasticsearch&#xff08;简称ES&#xff09;是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。它使用Java编写&#xff0c;基于Apache Lucene来构建索引和提供搜索功能&#xff0c;是一个分布式、可扩展、近实…

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

ORA-01092 ORA-14695 ORA-38301

文章目录 前言一、MAX_STRING_SIZE--12C 新特性扩展数据类型 varchar2(32767)二、恢复操作1.尝试恢复MAX_STRING_SIZE参数为默认值2.在upgrade模式下执行utl32k.sql 前言 今天客户发来一个内部测试库数据库启动截图报错&#xff0c;描述是“上午出现服务卡顿&#xff0c;然后重…

ODOO学习笔记(3):Odoo和Django的区别是什么?

Odoo和Django都是基于Python的开源框架&#xff0c;但它们的设计目标和用途有所不同&#xff1a; 设计目标和用途&#xff1a; Odoo&#xff1a;Odoo是一个企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;它提供了一套完整的商业管理软件&#xff0c;包括会计、库存…

零基础玩转IPC之——海思平台实现P2P远程传输实验(基于TUTK,国科君正全志海思通用)

老规矩&#xff0c;先做实验测试。以本店Hi3516EV200\GK7205开发板为例&#xff0c;其他开发板操作类似。 将源码包p2p-h264.tgz放到虚拟机&#xff0c;解压&#xff0c;编译 tar -jxvf p2p-h264.tgz cd p2p-h264 make clean make 得到可执行文件p2p-h264 启动开发板&…

如何理解DDoS安全防护在企业安全防护中的作用

DDoS安全防护在安全防护中扮演着非常重要的角色。DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一种常见的网络攻击&#xff0c;旨在通过向目标服务器发送大量请求&#xff0c;以消耗服务器资源并使其无法正常运行。理解DDoS安全防护的作用&#xff0c;可以从以下几个方面…

Python如何从HTML提取img标签下的src属性

目录 前提准备步骤1. 解析HTML内容2. 查找所有的img标签3. 提取src属性 完整代码 前提准备 在处理网页数据时&#xff0c;我们经常需要从HTML中提取特定的信息&#xff0c;比如图片的URL。 这通常通过获取img标签的src属性来实现。 在开始之前&#xff0c;你需要确保已经安装…

Redis主从复制(replication)

文章目录 是什么作用使用案例实操主从复制原理和工作流程slave启动&#xff0c;同步初请首次连接&#xff0c;全量复制心跳持续&#xff0c;保持通信进入平稳&#xff0c;增量复制从机下线&#xff0c;重连续传 复制的缺点 是什么 主从复制&#xff0c;master以写为主&#xf…

Android OpenGL ES详解——纹理:纹理过滤GL_NEAREST和GL_LINEAR的区别

目录 一、概念 1、纹理过滤 2、邻近过滤 3、线性过滤 二、邻近过滤和线性过滤的区别 三、源码下载 一、概念 1、纹理过滤 当纹理被应用到三维物体上时&#xff0c;随着物体表面的形状和相机视角的变化&#xff0c;会导致纹理在渲染过程中出现一些问题&#xff0c;如锯齿…

记录日志中logback和log4j2不能共存的问题

本文章记录设置两个日志时候&#xff0c;控制台直接报错 标黄处就是错误原因&#xff1a;1. SLF4J(W)&#xff1a;类路径包含多个SLF4J提供程序。 SLF4J(W)&#xff1a;找到提供程序[org.apache.logging.slf4j. net]。 SLF4J(W)&#xff1a;找到提供程序[ch.qos.log .classi…

【PGCCC】Postgresql Toast 原理

前言 上篇博客讲述了 postgresql 如何存储变长数据&#xff0c;它的应用主要是在 toast 。Toast 在存储大型数据时&#xff0c;会将它存储在单独的表中&#xff08;称为 toast 表&#xff09;。因为 postgresql 的 tuple&#xff08;行数据&#xff09;是存在在 Page 中的&…

C指针创建三维数组

定义的时候变量的位置就是最后一个星号的位置 int*** matrix3d_int(int nz, int nrh, int nch) {int*** matrix (int***)malloc(nz * sizeof(int**));for (int z 0; z < nz; z) {matrix[z] (int**)malloc(nrh * sizeof(int*));for (int y 0; y < nrh; y) {matrix[z][…