划分字母区间

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

 

示例:

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

提示:

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

class Solution {
public:
    vector<int> partitionLabels(string S) {//贪心算法和双指针
        int last[26]={0};
        int length = S.size();
        for(int i=0;i<length;i++){
            last[S[i] - 'a'] = i;//找出每一个小写字符最后出现的位置
        }
        vector<int> partition;
        int start =0,end = 0;//双指针,标记着每一段的开始和结束
        for(int i=0;i<length;i++){
            end = max(end,last[S[i] - 'a']);
            if(i == end){
                //已经找到满足当前字段出现的所有字符均在一个字段的约束条件
                //根据贪心原理,使得每个字段的长度最短
                partition.push_back(end - start+1);
                start = end+1;
            }
        }
        return partition;
    }
};

注意:

1.采用双指针,标记着每一段的开始和结束

2.第一遍遍历,确定出字符串中所有字符最后出现的位置

3.第二次遍历确定划分的片段和范围,注意始终更新end = max(end,last[S[i]-'a'])来保证当前字段出现的字符均出现在同一字段,使得满足约束条件

4.贪心原理的应用,当i == end的时候,说明找到一个可行的字段的结束,由于长度是不断递增的,所以第一次出现的即为长度最短的。由于每次取的片段都是最短片段,因此也就能获得最多的片段个数

 

posted @ 2020-10-24 11:04  zmachine  阅读(186)  评论(0编辑  收藏  举报