字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
提示:
- S的长度在[1, 500]之间。
- S只包含小写字母 'a' 到 'z' 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-labels
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
使用贪心算法。
首先遍历字符串,找到并且记录每个字母出现的最大下标。
对于某个字母,这个字母的最小下标和最大下标之间的序列必定在同一个片段中。同时为了要使片段尽可能多,我们使用双指针left,right从头遍历字符串。初始时,left=right=0,然后right取max(S[left]最大下标,right),left右移,以此类推。当left和right重合时,取到了该序列最大长度。记录这个长度。然后left继续右移,开始查找下一个序列即可。
代码:
class Solution {
private:
vector<int> ans;
public:
//
vector<int> partitionLabels(string S) {
int maxPos[26];
int length = (int)S.length();
for (int i = 0; i < length; ++i) {
maxPos[S[i]-'a'] = i;
}
int left = 0, right = 0;
int tmp = left;
while (left < length) {
right = max(right, maxPos[S[left]-'a']);
if (left == right) {
ans.push_back(right-tmp+1);
tmp = left+1;
}
++left;
}
return ans;
}
};