Description:
A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.
Example 1:
Input: S = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation:
The partition is "ababcbaca", "defegde", "hijhklij".
This is a partition so that each letter appears in at most one part.
A partition like "ababcbacadefegde", "hijhklij" is incorrect, because it splits S into less parts.
Note:
- S will have length in range [1, 500].
- S will consist of lowercase letters (‘a’ to ‘z’) only.
题意:将一个字符串进行最大数量的划分,要求划分后每个相同字符只出现在最多一个划分中;返回划分后的各部分的长度;
解法:遍历字符串 S S S,找到字符 S i S_i Si最后出现的位置 e d ed ed,之后我们在 [ i , e d ] [i,ed] [i,ed]范围内找出所有字符最后出现位置的最大值 m a x I n d e x maxIndex maxIndex,这个时候有下面两种情况;
- 如果 m a x I n d e x = = e d maxIndex == ed maxIndex==ed,则范围 [ i , e d ] [i, ed] [i,ed]就是其中一个划分;
- 否则,从位置 e d + 1 ed + 1 ed+1开始,直到 e d = = m a x I n d e x ed == maxIndex ed==maxIndex,其中 m a x I n d e x maxIndex maxIndex是遍历过程中每个字符最后出现位置的最大值;
Java
class Solution {
public List<Integer> partitionLabels(String S) {
int[] map = new int[26];
for (int i = 0; i < S.length(); i++) {
map[S.charAt(i) - 'a'] = i;
} //计算每个字符最后出现的位置
int st = 0;
int ed = 0;
List<Integer> res = new ArrayList<>();
while (st < S.length()) {
ed = map[S.charAt(st) - 'a'];
int maxIndex = st;
for (int i = st; i <= ed; i++) {
if (maxIndex < map[S.charAt(i) - 'a']) {
maxIndex = map[S.charAt(i) - 'a'];
}
} //计算范围[st, ed]内字符最后出现位置的最大值
if (maxIndex > ed) {
while (maxIndex != ed && ed != S.length()) {
ed++;
if (maxIndex < map[S.charAt(ed) - 'a']) {
maxIndex = map[S.charAt(ed) - 'a'];
}
}
}
res.add(ed - st + 1);
st = ed + 1;
}
return res;
}
}