763. 划分字母区间(力扣LeetCode)

763. 划分字母区间

题目描述

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

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

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

示例 1:

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

示例 2:

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

提示:

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

贪心算法

一想到分割字符串就想到了回溯,但本题其实不用回溯去暴力搜索。

题目要求同一字母最多出现在一个片段中,那么如何把同一个字母的都圈在同一个区间里呢?

如果没有接触过这种题目的话,还挺有难度的。

在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

可以分为如下两步:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

如图:
在这里插入图片描述

rfind函数

以下是对于给出的代码的详细注释,解释了它是如何解决问题的:

#include <vector>
#include <string>
using namespace std;class Solution {
public:vector<int> partitionLabels(string s) {vector<int> res; // 用于存储每个片段的长度int end=0; // 记录当前遍历到的所有字符中,最远的出现位置int cnt=0; // 当前片段的长度计数器// 遍历给定的字符串for(int i=0; i<s.size(); i++) {cnt++; // 每遍历一个字符,当前片段的长度加1// 更新当前片段中字符最远出现位置的最大值// s.rfind(s[i]) 返回字符s[i]最后一次出现的位置// 因为s.rfind的返回类型为size_t,可能与int类型的end不匹配,所以要进行类型转换end = max(end, (int)s.rfind(s[i]));// 如果当前字符是当前片段中最远出现位置的字符,// 则说明到目前为止的这一段可以独立为一个片段if (end == i) {// 将当前片段的长度添加到结果列表中res.push_back(cnt);// 重置计数器为下一个片段做准备cnt = 0;}}// 返回结果列表,包含了每个片段的长度return res;}
};

这段代码核心在于,通过遍历字符串,并使用end变量跟踪当前遍历到的所有字符中最远的出现位置。每当end与当前遍历的索引i相等时,说明到目前为止的这一段字符串可以划分为一个片段,因为它包含了一组字符,这些字符之后不再出现。然后,记录下这个片段的长度,并重置计数器和end变量,以便计算下一个片段的长度。最终,所有片段的长度被添加到结果列表中并返回。

易错:rfind函数返回值问题

在我没进行强制类型转换时,代码报错

Line 10: Char 17: error: no matching function for call to 'max'10 |             end=max(end,s.rfind(s[i]));|                 ^~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/algorithmfwd.h:407:5: note: candidate template ignored: deduced conflicting types for parameter '_Tp' ('int' vs. 'size_type' (aka 'unsigned long'))398 |     max(const _Tp&, const _Tp&);|     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_algo.h:3467:5: note: candidate template ignored: could not match 'initializer_list<_Tp>' against 'int'3458 |     max(initializer_list<_Tp> __l, _Compare __comp)|     ^

这个错误信息表明max函数无法匹配到合适的重载版本,原因是传递给max的两个参数ends.rfind(s[i])具有不同的类型。在C++中,rfind返回的是size_type类型,这通常是一个无符号整数类型(比如unsigned long),而end被定义为int类型,是一个有符号整数。

在C++标准库中,max要求两个参数具有相同的类型,因为它需要能够比较这两个参数并返回其中较大的一个。当你尝试使用两个不同类型的参数调用max时,编译器无法决定应该使用哪个类型来比较,因此会报错。

解决这个问题的一种方法是,确保max的两个参数类型一致。如果你确认end变量不会存储超过int类型能表示的范围的值,可以通过强制类型转换将rfind的返回值转换为int类型,如下所示:

end = max(end, (int)s.rfind(s[i]));

哈希表

这段代码是一个解决上述问题的C++实现。我将在代码的每一部分提供详细的注释来解释它的作用。

#include <vector>
#include <string>using namespace std;class Solution {
public:vector<int> partitionLabels(string s) {vector<int> res; // 创建一个空的整数向量来存储最后的片段长度结果// 数组用于记录每个字符最后出现的索引位置// 因为输入字符串只包含小写字母,所以只需要大小为26的数组int index[26];// 第一个循环遍历字符串s的每个字符for(int i = 0; i < s.size(); i++)// 计算字符到'a'的距离,作为数组索引,并更新这个字符对应的最后出现位置// 'a'的ASCII码将被用作基准点,所以任何字符都可以通过减去'a'得到一个0到25的索引值index[s[i] - 'a'] = i;// 初始化用于追踪当前片段最右端字符的索引int right = 0;int cnt = 0; // 计数器,用于记录当前片段的长度// 第二个循环同样遍历字符串的每个字符for(int i = 0; i < s.size(); i++) {// 增加当前片段的计数器cnt++;// 通过字符索引,找到当前片段最右端字符的索引,与当前的`right`比较,取较大者// 这样可以确保当前片段包含所有已遍历字符的最后出现right = max(right, index[s[i] - 'a']);// 如果当前字符的位置i与`right`相等,说明当前片段不会再扩展了if(right == i) {// 把当前片段的长度加入到结果集res.push_back(cnt);// 重置计数器,为下一个片段准备cnt = 0;}}// 返回分段的长度数组return res;}
};

该代码分为两个主要部分:第一部分遍历字符串,记录每个字符最后出现的位置;第二部分再次遍历字符串,根据每个字符的最后出现位置,确定每个片段的边界并记录其长度。

这种方法能够确保每个字符仅出现在一个片段中,且得到的片段数目是最大化的。最终,我们得到一个数组,记录了根据给定规则得到的每个片段的长度。

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

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

相关文章

Web开发基本流程

Web是全球广域网&#xff0c;能够通过浏览器访问的网站。我们要访问网站&#xff0c;首先要在浏览器输入对应的域名。 浏览器也是一个程序&#xff0c;京东的网站也是一个程序&#xff0c;在京东那边电脑运行着&#xff0c;我们只是通过浏览器远程访问。京东的程序由三个部分组…

【题目】【网络系统管理】2022 年全国职业院校技能大赛 网络系统管理赛项 模块 A:网络构建

2022 年全国职业院校技能大赛 网络系统管理赛项 模块 A&#xff1a;网络构建 目录 考试说明 … 3 任务描述 … 3 任务清单 … 3 &#xff08;一&#xff09;基础配置 … 3 &#xff08;二&#xff09;有线网络配置 … 4 &#xff08;三&#xff09;无线网络配置 … 5 &…

深入解析MD5哈希算法:原理、应用与安全性

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 本文将深入探讨MD5哈希算法的工作原理、应用场景以及安全性问题。我们将了解MD5如何生成固定长度的哈希值&#xff0c;以及它在数…

PHiSeg:捕捉医学图像分割中的不确定性

PHiSeg&#xff1a;捕捉医学图像分割中的不确定性 摘要引言方法 PHiSeg Capturing Uncertainty in Medical Image Segmentation 摘要 解剖结构和病理的分割本质上是模糊的。例如&#xff0c;结构边界可能不清晰可见&#xff0c;或者不同的专家可能具有不同的注释风格。大多数当…

C++ 之多态虚函数原理及应用

文章目录 多态基本概念和原理虚函数的基本原理和概念虚析构和纯虚析构多重继承中的虚函数小结 多态基本概念和原理 多态的基本概念 **多态是C面向对象三大特性之一** 多态的定义 多态是一种面向对象编程概念&#xff0c;指同一个行为&#xff08;方法&#xff09;在不同的对象上…

Java上机实验报告(4)

实验 &#xff08;4&#xff09; 项目名称&#xff1a;子类与继承-求圆柱和圆锥 一、 实验报告内容一般包括以下几个内容&#xff1a; 实验项目名称 实验4 子类与继承-求圆柱和圆锥实验目的和要求 本实验的目的&#xff1a; &#xff08;1&#xff09;掌握&#xff08;继承&a…

【前端学习——js篇】5.事件循环

详细&#xff1a;https://github.com/febobo/web-interview 5.事件循环 js是一种单线程语言&#xff0c;同一时间内只能做一件事情&#xff0c;为了避免单线程阻塞的方法就是事件循环。 在javascript当中&#xff0c;所有的任务都可以分为&#xff1a; 同步任务&#xff1a;按…

Windows10 Version22h2 补丁kb5034441更新失败

By wdhuag 20240328 参考: Windows10安装KB5034441更新报错0x80070643_2024-01 适用于 windows 10 version 22h2 安全更新,适合基于 x64 -CSDN博客 windows10&#xff08;KB5034441&#xff09;更新失败报错 0x80070643解决方法_kb5034441更新失败-CSDN博客 如何修复 Windo…

双通道内存@DDR5多通道内存

文章目录 多通道内存DDR4及以前的内存的双通道DDR5往后的双通道和多通道半位宽4通道组合 其他组合测试 DDR5介绍概览重要Features特点 总结 多通道内存 DDR4及以前的内存的双通道 双通道内存是一种内存架构设计&#xff0c;通过在主板上配置两个或多个独立且同时工作的内存控制…

管理阿里云服务器ECS -- 网站选型和搭建

小云&#xff1a;我已经学会了如何登录云服务器ECS了&#xff0c;但是要如何搭建网站呢&#xff1f; 老王&#xff1a;目前有很多的个人网站系统软件&#xff0c;其中 WordPress 是使用非常广泛的一款&#xff0c;而且也可以把 WordPress 当作一个内容管理系统&#xff08;CMS…

使用yolov9来实现人体姿态识别估计(定位图像或视频中人体的关键部位)教程+代码

yolov9人体姿态识别&#xff1a; 相较于之前的YOLO版本&#xff0c;YOLOv9可能会进一步提升处理速度和精度&#xff0c;特别是在姿态估计场景中&#xff0c;通过改进网络结构、利用更高效的特征提取器以及优化损失函数等手段来提升对复杂人体姿态变化的捕捉能力。由于YOLOv9的…

架构师之路--docker命令实践整理

安装docker sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine sudo yum install -y yum-utils sudo yum-config-manager --add-repo http://mirrors.aliyun.com/…

开源博客项目Blog .NET Core源码学习(12:App.Application项目结构分析)

开源博客项目Blog的App.Application项目主要定义网站页面使用的数据类&#xff0c;同时定义各类数据的增删改查操作接口和实现类。App.Application项目未安装Nuget包&#xff0c;主要引用App.Core项目的类型。   App.Application项目的顶层文件夹如下图所示&#xff0c;下面逐…

巨控GRM110系列:短距离内的无线通讯模块

标签: #巨控GRM110 #无线通讯 #ROLA技术 #工业自动化 #远程数据采集 在工业自动化和智能制造的领域中&#xff0c;数据的准确传输是实现高效生产的关键。随着技术的不断进步&#xff0c;无线通讯技术已成为破解远距离数据传输难题的利器。今天&#xff0c;我们将聚焦于一款革命…

U盘未格式化?数据恢复大揭秘!

在日常办公和生活中&#xff0c;U盘已成为我们不可或缺的数据存储工具。然而&#xff0c;有时我们会遇到这样一个令人头疼的问题&#xff1a;原本正常使用的U盘&#xff0c;突然提示“未格式化”&#xff0c;里面的文件似乎都消失不见了。面对这种情况&#xff0c;很多人会感到…

线程池-1:线程池是如何复用线程的?

这段代码实现了一个简单的线程池 SimpleThreadPool。主要包括以下几个关键部分&#xff1a; 构造函数&#xff1a;初始化最大线程数 maxPoolSize、任务队列 taskQueue、当前线程数 currentPoolSize&#xff0c;以及锁 lock 和条件 taskAvailable。 submit(Runnable task) 方法…

FPGA时钟资源详解(2)——Clock-Capable Inputs

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 1.1 为什么使用CC 1.2 如何使用CC 二、Clock-Capable Inputs 2.1 SRCC 2.2 MRCC 2.3 其他用途 2.3.1…

LeetCode 135. 分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需要准备的…

C语言中连字符“#”的使用,输出固件的编译时间和版本号

首先我们使用C语言宏定义和“#”来组合字符串 #define MAINVER 2#define SUBVER1 0#define SUBVER2 1#define STR(s) #s#define VERSION(a,b,c) "System V" STR(a) "." STR(b) "." STR(c) " "__DATE__ 然后我们在全局变量中定义一…

VsCode的json文件不允许注释的解决办法

右下角找到注释点进去 输入Files: Associations搜索出此项 改为项为*.json值为jsonc保存即可 然后会发现VsCode的json文件就允许注释了