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.

题意:将一个字符串进行最大数量的划分,要求划分后每个相同字符只出现在最多一个划分中;返回划分后的各部分的长度;

解法:遍历字符串LeetCode-Partition Labels_Two Pointers,找到字符LeetCode-Partition Labels_LeetCode_02最后出现的位置LeetCode-Partition Labels_Greedy_03,之后我们在LeetCode-Partition Labels_Two Pointers_04范围内找出所有字符最后出现位置的最大值LeetCode-Partition Labels_Two Pointers_05,这个时候有下面两种情况;

  • 如果LeetCode-Partition Labels_i++_06,则范围LeetCode-Partition Labels_字符串_07就是其中一个划分;
  • 否则,从位置LeetCode-Partition Labels_LeetCode_08开始,直到LeetCode-Partition Labels_Greedy_09,其中LeetCode-Partition Labels_Two Pointers_10是遍历过程中每个字符最后出现位置的最大值;
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;
}
}