力扣hot100:划分字母区间

题目描述:

题目解析:

题目要求对字符串进行分割,使得每个字母最多只出现在一个分割片段中

在满足这个条件的前提下,需要返回每个分割片段的长度。

换句话说:

  1. 同一个字符不能跨越多个片段

  2. 一旦某个字符出现在当前片段中,那么这个片段必须包含该字符在字符串中的所有出现位置

  3. 分割后的片段要尽可能靠前、数量尽可能多

因此,本题的本质并不是"随意切字符串",而是要找到一种合理的切分方式,使字符的出现范围不会被打断。

思路分析:

解决这道题的关键,在于提前知道每个字符最远会出现到哪里。

1. 预处理字符的最后位置

由于字符串只包含小写字母,可以先遍历字符串,记录每个字符在字符串中最后一次出现的下标。

这样一来,当我们在某个位置看到一个字符时,就能立刻知道:当前分割区间至少要延伸到这个字符的最后出现位置。

2. 用区间合并的思路遍历字符串

接下来,从左到右遍历字符串,并维护一个"当前分割区间":区间的左端点是当前片段的起始位置。区间的右端点表示:当前片段必须覆盖到的最远位置。在遍历过程中,每遇到一个字符,就用它的最后出现位置来更新当前区间的右端点,保证这个字符不会出现在区间之外。

3. 何时可以完成一次分割

当遍历位置刚好走到当前区间的右端点时,说明:当前片段中出现的所有字符都已经完整地包含在这个区间内不会再延伸到后面的位置此时就可以安全地切分出一个片段,记录它的长度,并从下一个位置开始新的片段。

4. 思路本质

从整体来看,这道题的核心思想可以概括为:先确定每个字符的"活动范围",再把这些范围不断合并成若干不重叠的区间,每一个最终合并完成的区间,就是一个合法的分割片段

代码:

java 复制代码
class Solution {
    public List<Integer> partitionLabels(String s) {
        char[] a=s.toCharArray();
        int n=a.length;
        int[] last=new int[26];
        for(int i=0;i<n;i++){
            last[a[i]-'a']=i;
        }
        List<Integer> res=new ArrayList<>();
        int start=0,end=0;
        for(int i=0;i<n;i++){
            end=Math.max(last[a[i]-'a'],end);
            if(i==end){
                res.add(end-start+1);
                start=end+1;
            }
        }
        return res;
    }
}
相关推荐
那个村的李富贵2 小时前
CANN加速下的AIGC“即时翻译”:AI语音克隆与实时变声实战
人工智能·算法·aigc·cann
power 雀儿2 小时前
Scaled Dot-Product Attention 分数计算 C++
算法
琹箐2 小时前
最大堆和最小堆 实现思路
java·开发语言·算法
renhongxia13 小时前
如何基于知识图谱进行故障原因、事故原因推理,需要用到哪些算法
人工智能·深度学习·算法·机器学习·自然语言处理·transformer·知识图谱
坚持就完事了3 小时前
数据结构之树(Java实现)
java·算法
算法备案代理3 小时前
大模型备案与算法备案,企业该如何选择?
人工智能·算法·大模型·算法备案
赛姐在努力.3 小时前
【拓扑排序】-- 算法原理讲解,及实现拓扑排序,附赠热门例题
java·算法·图论
野犬寒鸦4 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总4 小时前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
rainbow68895 小时前
深入解析C++STL:map与set底层奥秘
java·数据结构·算法