菜鸟刷题之路——Q23:划分字母区间

问题:763. 划分字母区间在这里插入图片描述

分析

分析:为了切分最多的字符串,我们希望每个字符串尽可能的短,这一步即为贪心的思想。

但是我们如何保证我们切分的字符串是符合题目意思的呢?拿S为例子:

  • 变量说明:stratIndex:当前子串的开始下标,rearIndex当前子串的结尾下标。

  • 首先:a字符最后出现的下标为8,我们假设第一个字符的长度为a第一次出现到最后一次出现的长度,这个是可能的最小的长度,此时得到了子串s1,其startIndex为0,rearIndex为8;

  • 为了保证s1是满足条件的,我们遍历s1的子串中的元素是否都满足题目的要求,即从b开始,再判断b最后一次出现的位置是否是在子串内,对于s1来说是满足的,即在0-8内的字符出现的位置都没有超过这个范围

  • 遍历完s1你会发现长度刚好为9,此时从d开始找,d的下标为9,最后一次出现的下标为14,此时子串的长度为6,那么我们开始检查我们的子串s2;

  • 从9开始,一直到当前的rearIndex,**注意这个rearIndex可能是会更新的。**对于s2来说,e的出现范围超过了一开始记录的rearIndex,**那么我们需要更新rearIndex,以记录正确的子串长度。**最终s2的startIndex为9,rearIndex为15,。

  • 对于s3来说也是一样的。

  • 注意:字符串"qiejxqfnqceocmy"是一种需要注意的情况:

    • 首先看q最后一次出现的位置为8,即startIndex=0,rearIndex=8。
    • 检测字符串:在原来的子串中的字符只有e出现在了子串范围之外,那么更新到e最后一次出现的位置,此时c被包括进来了,c最后一次出现的位置为12,即某次的rearIndex更新可能会引发更多的rearIndex更新,所以在检查字符串的时候,我们应该从startInde一直检查到最新的rearIndex。

Code

class Solution {
    public List<Integer> partitionLabels(String S) {
        List<Integer> ls = new ArrayList();
        if (S.length() == 0) return ls;
        char[]  chars = S.toCharArray();
        // 用于从后向前找到最后一个出现的字符的下标。
        int rearIndex = chars.length, arrLength = chars.length;
        for (int startIndex = 0; startIndex < arrLength; startIndex = ++rearIndex) {            
            rearIndex = arrLength;
            char ch = chars[startIndex];

            while (--rearIndex > startIndex && ch != chars[rearIndex]);
            //  保证我们的贪心策略是正确的
            // 我们需要检查我们找的序列是否满足条件
            int count = rearIndex;
            int num = startIndex;
            // 这里一定是小于count,因为你新加入的字符也可能导致最后的字符串变长
            while (++num < rearIndex) {
                ch = chars[num];
                int index = arrLength;  
                while (--index > count && ch != chars[index]);
                count = index;
            }
            rearIndex = count;
            // 存储长度
            ls.add(rearIndex - startIndex + 1);
        }
        return ls;
    }
}

结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Q21: Which of the following is a valid user-defined output stream manipulator header? a. ostream& tab( ostream& output ) b. ostream tab( ostream output ) c. istream& tab( istream output ) d. void tab( ostream& output ) Q22: What will be output by the following statement? cout << showpoint << setprecision(4) << 11.0 << endl; a. 11 b. 11.0 c. 11.00 d. 11.000 Q23: Which of the following stream manipulators causes an outputted number’s sign to be left justified, its magnitude to be right justified and the center space to be filled with fill characters? a. left b. right c. internal d. showpos Q24: Which of the following statements restores the default fill character? a. cout.defaultFill(); b. cout.fill(); c. cout.fill( 0 ); d. cout.fill( ' ' ); Q25: When the showbase flag is set: a. The base of a number precedes it in brackets. b. Decimal numbers are not output any differently. c. "oct" or "hex" will be displayed in the output stream. d. Octal numbers can appear in one of two ways. Q26: What will be output by the following statements? double x = .0012345; cout << fixed << x << endl; cout << scientific << x << endl; a. 1.234500e-003 0.001235 b. 1.23450e-003 0.00123450 c. .001235 1.234500e-003 d. 0.00123450 1.23450e-003 Q27: Which of the following outputs does not guarantee that the uppercase flag has been set? a. All hexadecimal numbers appear in the form 0X87. b. All numbers written in scientific notation appear the form 6.45E+010. c. All text outputs appear in the form SAMPLE OUTPUT. d. All hexadecimal numbers appear in the form AF6. Q28: Which of the following is not true about bool values and how they're output with the output stream? a. The old style of representing true/false values used -1 to indicate false and 1 to indicate true. b. A bool value outputs as 0 or 1 by default. c. Stream manipulator boolalpha sets the output stream to display bool values as the strings "true" and "false". d. Both boolalpha and noboolalpha are “sticky” settings.
05-24

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值