108.划分字母区间

本文详细介绍了如何使用滑动窗口算法解决一个字符串片段划分问题,确保每个片段中字符不重复。通过示例解析了算法思路,并提供了具体的Java代码实现。此方法巧妙地利用了字符最大索引信息,有效地进行区间判断和更新。
摘要由CSDN通过智能技术生成

一、题目描述

字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
在这里插入图片描述

二、解题思路

使用滑动窗口来解决,根据上面的示例,其实可以把每个片段看成是一个窗口,只要保证当前窗口中出现的字符不会出现在其它窗口即可,下面模拟一下这个过程:
在这里插入图片描述
第一步:对于第一个字符a,看它最远出现在如下的位置:
在这里插入图片描述
说明当前片段至少是leftright之间,那最终是不是还要取决于这个区间其它元素最远出现的位置是不是在当前right之后,所以要依次遍历当前区间内的元素,直到遍历完为止,发现没有元素超过这个right的位置,所以得到第一个片段:
在这里插入图片描述
第二步:left后移到right+1的位置,该位置元素是d,然后right移动到第二个d最远出现的位置,当前区间就是第二个片段至少可能的区间,依然要区间内遍历元素判断:
在这里插入图片描述
然后遍历区间内的元素e,它出现的第二个位置在当前right后面,right移动到这个位置:
在这里插入图片描述
继续遍历其它元素,没有第二次出现超过当前right的,所以得到第二个片段,长度为right-left+1
在这里插入图片描述
接下来就重复上面步骤即可。

三、代码演示

class Solution {
    public List<Integer> partitionLabels(String s) {
         //计算并存储每个字符在数组中所在的最大索引
        int[] c2Index = new int[26];
        for (int i=0; i<s.length();i++){
            //得到的是最大索引,也就是最远的那个值
            c2Index[s.charAt(i)-'a'] = i;
        }

        //存储最终结果
        List<Integer> res = new ArrayList<>();

        //维护窗口
        int left=0, right=0;
        for (int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            right = Math.max(right, c2Index[c-'a']);
            if (i==right){
                res.add(right-left+1);
                left = right+1;
            }
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值