力扣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;
    }
}
相关推荐
超级码力66617 小时前
【Latex文件架构】Latex文件架构模板
算法·数学建模·信息可视化
穿条秋裤到处跑17 小时前
每日一道leetcode(2026.04.29):二维网格图中探测环
算法·leetcode·职场和发展
Merlos_wind18 小时前
HashMap详解
算法·哈希算法·散列表
汉克老师18 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
Yzzz-F20 小时前
Problem - 2205D - Codeforces
算法
智者知已应修善业21 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn21 小时前
Java Set集合相关知识点
java·开发语言·算法
生成论实验室1 天前
《事件关系阴阳博弈动力学:识势应势之道》第四篇:降U动力学——认知确定度的自驱演化
人工智能·科技·神经网络·算法·架构
AI科技星1 天前
全域数学·72分册:场计算机卷【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
科研前沿1 天前
镜像孪生VS视频孪生核心技术产品核心优势
大数据·人工智能·算法·重构·空间计算