leetcode 763

763.划分字母区间
力扣题目链接(opens new window)

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

示例: 输入:S = “ababcbacadefegdehijhklij” 输出:[9,7,8] 解释: 划分结果为 “ababcbaca”, “defegde”, “hijhklij”。 每个字母最多出现在一个片段中。 像 “ababcbacadefegde”, “hijhklij” 的划分是错误的,因为划分的片段数较少。

提示:

S的长度在[1, 500]之间。
S只包含小写字母 ‘a’ 到 ‘z’ 。

   public List<Integer> partitionLabels(String s) {
        //真有给无语到,想了好久的方法,最终还是没答案的骚
        //如何检测一个单词中字母最后出现的下标
        int []tap=new int [26];
        List<Integer>list1=new ArrayList<>();
        for(int i=0;i<s.length();i++){
            tap[s.charAt(i)-'a']=i;
        }
        //最巧妙地是这里,统计一个单词在字符串中最后出现的次数竟然能用这种思路。比如char 0为b,那么tap【1】=0;然后后续比如最后i=7时
       // char 7也为b,此时 tap【1】=7,也就是b最后出现的下标就为7
        //这样就能得到每个字母最后出现的下标
        //s.charAt(i)-'a' 这里意思就是更新相同字母最后出现的下标
        
        int left=0;
        int right=0;
        for(int i=0;i<s.length();i++){
        //典型的贪心
        //一开始总觉得要搞成小于等于,其实贪心的题就用等于就好
        //类比这道题,直接每一次都更新更长的。一开始想应该在范围内才更新,但后面发现下面有在判断啦,
        //直接更新就行,下面如果等于就说明已经到了目前范围所能到达的最远
		//很巧妙,一开始的想法 在这些细节上总是会出错,多做吧,或许做多了就融会贯通了
            right=Math.max(right,tap[s.charAt(i)-'a']);
            if(i==right){
                list1.add(right-left+1);
                left=right+1;
            }
        }

            return list1;

反正记住这种思路吧,很少用 小于判断
大多数都是 直接更新,然后下面的等于 作为约束条件。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值