力扣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;
    }
}
相关推荐
xhbaitxl8 分钟前
算法学习day38-动态规划
学习·算法·动态规划
多恩Stone9 分钟前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc
历程里程碑11 分钟前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
pp起床12 分钟前
贪心算法 | part02
算法·leetcode·贪心算法
sin_hielo12 分钟前
leetcode 1653
数据结构·算法·leetcode
2501_9011478314 分钟前
面试必看:优势洗牌
笔记·学习·算法·面试·职场和发展
YuTaoShao24 分钟前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法二)排序 + 二分查找
数据结构·算法·leetcode
wangluoqi24 分钟前
26.2.6练习总结
数据结构·算法
Q741_14728 分钟前
C++ 优先级队列 大小堆 模拟 力扣 703. 数据流中的第 K 大元素 每日一题
c++·算法·leetcode·优先级队列·
网安墨雨31 分钟前
Python自动化一------pytes与allure结合生成测试报告
开发语言·自动化测试·软件测试·python·职场和发展·自动化