You are given a string s. We want to partition the string into as many parts as possible so that each letter appears in at most one part.
Note that the partition is done so that after concatenating all the parts in order, the resultant string should be s.
Return a list of integers representing the size of these parts.
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.
Input: s = "eccbbbbdec"
Output: [10]
1 <= s.length <= 500s consists of lowercase English lettersThis problem can be solved using a greedy approach with the help of a hash map:
To ensure each letter appears in at most one partition, we need to know the last occurrence of each character in the string. A partition can only end when we've reached the last occurrence of all characters seen so far in the current partition.
start: marks the beginning of the current partitionend: marks the farthest last occurrence we've seen so fari:
end to be the maximum of current end and the last occurrence of s[i]i == end, we've reached the end of the partition (all characters in this partition won't appear later)i == end, add the partition size (end - start + 1) to the result and update start = i + 1The greedy choice is to make partitions as early as possible. As soon as we reach a point where we've seen the last occurrence of all characters in the current partition, we immediately create a partition there.
For s = "ababcbacadefegdehijhklij":
{a:8, b:5, c:7, d:14, e:15, f:11, g:13, h:19, i:22, j:23, k:20, l:21}a), end = 8 (last a)b), end = max(8, 5) = 8i == end, partition size = 9class Solution {
public List<Integer> partitionLabels(String s) {
// Record last index of each character
Map<Character, Integer> lastIndex = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
lastIndex.put(s.charAt(i), i);
}
List<Integer> result = new ArrayList<>();
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
// Update end to the farthest last occurrence
end = Math.max(end, lastIndex.get(s.charAt(i)));
// If we've reached the end of the partition
if (i == end) {
result.add(end - start + 1);
start = i + 1;
}
}
return result;
}
}
def partitionLabels(s: str) -> List[int]:
# Record last index of each character
last_index = {char: i for i, char in enumerate(s)}
result = []
start, end = 0, 0
for i, char in enumerate(s):
# Update end to the farthest last occurrence
end = max(end, last_index[char])
# If we've reached the end of the partition
if i == end:
result.append(end - start + 1)
start = i + 1
return result
For s = "ababcbacadefegdehijhklij":
Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Char: a b a b c b a c a d e f e g d e h i j h k l i j
| | |
Part 1 Part 2 Part 3
(9 chars) (7 chars) (8 chars)
{a, b, c} and their last occurrences are all within this partition{d, e, f, g} and their last occurrences are all within this partition{h, i, j, k, l} and their last occurrences are all within this partition