当前位置: 首页 > news >正文

划分字母区间-leetcode

题目描述

给你一个字符串 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]

提示:

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

解法一

思路:

记录出所有字符出现的最后一个位置。对于最后一个字符的位置是当前索引的时候可以记为0,作为分割位置的候选位置。依次遍历候选位置,如果候选位置前所有的字符最后位置小于当前索引,则可以进行分割。

代码:

class Solution {public List<Integer> partitionLabels(String s) {int[] charIndex=new int[s.length()];List<Integer> index=new ArrayList<>();List<Integer> res = new ArrayList<>();for(int i = 0; i < s.length(); i++){charIndex[i]=s.lastIndexOf(s.charAt(i));if(i==s.lastIndexOf(s.charAt(i))){charIndex[i]=0;index.add(i);}}int lastIndex=0;for(int i=0; i<index.size(); i++){int indexAns=index.get(i);int j=lastIndex;for(; j<indexAns; j++){if(charIndex[j]>indexAns)break;}if(j==indexAns){res.add(indexAns-lastIndex+1);lastIndex=j+1;}}return res;}
}

解法二

思路:

来自官方题解。

由于同一个字母只能出现在同一个片段,显然同一个字母的第一次出现的下标位置和最后一次出现的下标位置必须出现在同一个片段。因此需要遍历字符串,得到每个字母最后一次出现的下标位置。

在得到每个字母最后一次出现的下标位置之后,可以使用贪心的方法将字符串划分为尽可能多的片段,具体做法如下。

从左到右遍历字符串,遍历的同时维护当前片段的开始下标 start 和结束下标 end,初始时 start=end=0。

  • 对于每个访问到的字母 c,得到当前字母的最后一次出现的下标位置 endc,则当前片段的结束下标一定不会小于 endc,因此令 end=max(end,endc)。

  • 当访问到下标 end 时,当前片段访问结束,当前片段的下标范围是 [start,end],长度为 end−start+1,将当前片段的长度添加到返回值,然后令 start=end+1,继续寻找下一个片段。

重复上述过程,直到遍历完字符串。

上述做法使用贪心的思想寻找每个片段可能的最小结束下标,因此可以保证每个片段的长度一定是符合要求的最短长度,如果取更短的片段,则一定会出现同一个字母出现在多个片段中的情况。由于每次取的片段都是符合要求的最短的片段,因此得到的片段数也是最多的。

由于每个片段访问结束的标志是访问到下标 end,因此对于每个片段,可以保证当前片段中的每个字母都一定在当前片段中,不可能出现在其他片段,可以保证同一个字母只会出现在同一个片段。

代码:

class Solution {public List<Integer> partitionLabels(String s) {int[] last = new int[26];int length = s.length();for (int i = 0; i < length; i++) {last[s.charAt(i) - 'a'] = i;}List<Integer> partition = new ArrayList<Integer>();int start = 0, end = 0;for (int i = 0; i < length; i++) {end = Math.max(end, last[s.charAt(i) - 'a']);if (i == end) {partition.add(end - start + 1);start = end + 1;}}return partition;}
}
http://www.jsqmd.com/news/602188/

相关文章:

  • 像素时装锻造坊应用场景:游戏原画师的AI皮装设计工作流全解析
  • 跨设备媒体传输高效解决方案:Go2TV实现多场景无缝投屏体验
  • CVPR 2023顶会模型复现避坑指南:在Ubuntu 20.04上用3块1080Ti跑通CDDFuse
  • LN4056A 1.0A 具有 USB 接口兼容的线性电池管理芯片
  • 3个效率飞跃:douyin-downloader如何实现智能采集自动化
  • Day_1
  • 告别模型下载:零门槛上手EdgeTTS,微软语音合成服务一键调用
  • 渗透测试神器Cobalt Strike的监听器配置避坑指南(含最新4.8版本变化)
  • 考研复试简历避坑指南:从‘花哨’到‘充实’,人大计算机学长教你90天填充技术背景
  • 运维新手零基础入门:借助快马AI生成你的第一个日志分析脚本
  • KIHU快狐|15.6寸壁挂广告机安卓系统楼宇电梯高清信息发布屏
  • 当你的JSON文件需要说多国语言:一个开发者的国际化救星
  • SeuratWrappers:如何高效扩展你的单细胞分析能力?
  • 人形机器人控制系统延迟优化实战:从5G-A到TSN的完整解决方案
  • 兰亭妙微加载体验设计白皮书:从骨架屏到后台加载的全场景优化策略
  • 告别Unity默认编辑器:手把手教你用VSCode配置C#开发环境(附插件清单)
  • 南麟LN6206 低功耗 低压差 中输出电流CMOS稳压器芯片 多种封装形式
  • 技术奇点移民局:人类文明延续证书申领指南
  • 终极指南:用G-Helper免费掌控华硕笔记本性能与散热
  • OpenClaw+千问3.5-9B内容审核:自动检查文本合规性
  • 实时社交互动分析系统:技术架构与实践应用
  • 开源SRAM设计工具:重新定义芯片设计效率的革新性方案
  • ESPectre + Home Assistant快速实现WiFI-CSI 可视化方案
  • 革新性宝可梦数据自动化工具:AutoLegalityMod插件全解析
  • 揭秘银行核心系统C++内存池崩溃真相:基于真实生产环境的17GB/日内存碎片数据复盘
  • BepInEx插件框架:让Unity游戏模组化变得如此简单
  • 终极词库自由:深蓝词库转换器让你的输入习惯跨平台无缝迁移
  • 如何高效管理iOS种子下载 轻松获取文件资源
  • STM32与PulseSensor实战:动态阈值算法优化心率检测精度
  • 终极E-Hentai漫画下载指南:一键批量保存你的数字收藏