Partition Labels
MediumThe problem
Cut the string s into as many pieces as possible so that no letter shows up in more than one piece. The pieces, joined back in order, must give s again. Return the length of each piece, in order.
- Example 1Input: s = "ababcbacadefegdehijhklij"Output: [9, 7, 8]
The pieces are "ababcbaca", "defegde" and "hijhklij". Every letter lives in only one piece.
- Example 2Input: s = "eccbbbbdec"Output: [10]
The first letter e also appears at the very end, so the whole string must be one piece.
- 1 ≤ len(s) ≤ 100,000
- s has only lowercase English letters
Write it in Go. Try for about 20 minutes on paper first, then open one hint at a time.
Try it here
Write Go. Common packages like fmt and sort are imported for you. Keep the function name and inputs the same.
Hints, one at a time
Nudge
A piece must contain every occurrence of each of its letters. How far must it extend?
The idea
Record the last index of each letter; scan, extending the current end to the max last index; when i reaches end, cut a piece.
Target: O(n) time
Go function shape
func partitionLabels(s string) []intReference solution
Tested with go test. Try it yourself first, then compare.
// PartitionLabels: split s so each letter appears in at most one part; return the part sizes.
// Greedy: a part must reach at least the last occurrence of every letter inside it.
func PartitionLabels(s string) []int {
last := map[rune]int{}
for i, r := range s {
last[r] = i
}
var sizes []int
start, end := 0, 0
for i, r := range s {
end = max(end, last[r]) // extend the part to cover this letter's last occurrence
if i == end { // nothing inside the part appears later: close it
sizes = append(sizes, end-start+1)
start = i + 1
}
}
return sizes
}