leetcode记录-763-划分字母区间-贪心

763.划分字母区间

在这里插入图片描述

差点掉进坑的思路(不对,别看,自己的记录)

本来想记录每个字母出现的首下标和尾下标,得到一个有24个区间的数组。然后求这个区间数组的独立并集(只有相交才求并集,下次看相交跟并集比)数目,然后在找每个字母出现的首下标和尾下标的时候,企图遍历。。。。。。太夸张了。。。。。还好突然灵光一闪百度了String中某个字符出现的首下标和尾下标的方法,以及String获取某下标的字符的方法。。。。但是遍历得到数组然后再求独立并集数好像和直接求没啥区别,多此一举,因此有了下面的思路。

思路

  1. 两个标志:一个begin记录当前集合的开始下标,end记录当前集合的结束下标。
  2. 从第一个字符开始,begin为0,end为其最后出现的下标,开始从第二个字符遍历,如果在begin和end间出现了一个字符,他的最后出现下标>end,就更新end。
  3. 否则,如果当前下标>end了,证明来到了新的集合,这时把上个区间的长度加到List里,更新begin为当前的i,end为这个字符最后出现的下标。
  4. 最后,还有一种情况要考虑:当下标来到最后一个字符,存在两种情况①这个字符是新子串的开始,这个子串只有一个字符②这个字符不是新子串的开始 —— 这两种情况都需要将最后的子串长度加到List里,因为步骤2/3分别针对这两种情况,但是2没有加长度到List,3条件是i>end,但是这种情况i=end。因此这种情况,就直接把最后的子串长度加进去。

代码

class Solution {
    public List<Integer> partitionLabels(String s) {
        int begin=0;
        int end=s.lastIndexOf(s.charAt(0));  //首字母的最后一次出现
        List<Integer> numberS = new ArrayList<>(); //list初始化
        for (int i = 1; i < s.length(); i++) {
            if(i<end&&s.lastIndexOf(s.charAt(i))>end){ //还是老串
                end=s.lastIndexOf(s.charAt(i)); //如果区间内有新字符,且其最后一次出现比目前的end更大,end更新
            }else if (i>end){ //当开始新的串
                numberS.add(end-begin+1);
                begin=i;
                end=s.lastIndexOf(s.charAt(i));
            }
            if (i==s.length()-1) //到最后一个元素,不管其时新的串第一个还是他是老的串,都直接输出最后一个结果!!要是没这个就会少一个数
                numberS.add(end-begin+1);
        }
        //如果有交集,求并集,看最终有几个并集。
        return numberS;
    }
}

技巧

  1. List初始化:List<Integer> numberS = new ArrayList<>();注意new的不是List。
  2. List添加元素:numberS.add(end-begin+1);
  3. 字符串s的某字符第一次出现的下标:int a=s.indexOf('q');
  4. 字符串s的某字符最后一次出现的下标:int b=s.lastIndexOf('q');
  5. 字符串某个下标的字符:s.charAt(0)
  6. 字符串长度:s.length(),注意有括号,数组长度没括号。
  7. 本题中给出返回值为List,自己也要明白对于这种不确定长度的数组,需要首先声明为List,后面根据情况toArray为数组。
  8. 本题一个begin和一个end,记录的是满足调价子区间的首尾,而一个一个元素步进是在for循环里,begin记录了当前子串的开始,i步进当大于end证明进入新的子串,这时[begin,end]区间内的元素即满足条件的,记录,然后begin更新为当前end,end更新为当前begin处字符最后出现的位置。而且for里的i必须一个一个加,直接跳到end的话漏掉太多。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值