Partition Labels — Solution in Python, Java & C++
Partition Labels solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Partition Labels is a medium coding problem on strings, hash table and greedy.
- Difficulty: Medium
- Topics: Strings, Hash Table, Greedy, Two Pointers
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Partition the string s into as many parts as possible so that no letter appears in more than one part (concatenating the parts in order must reproduce s).
Return a list of the sizes of these parts.
Example 1
Input: s = "ababcbacadefegdehijhklij"
Output: [9,7,8]
Explanation: Parts: "ababcbaca", "defegde", "hijhklij".
Example 2
Input: s = "eccbbbbdec"
Output: [10]
Constraints
1 <= s.length <= 40Lowercase English letters.
Hints for Partition Labels
Hint 1
Record the last index of every letter.
Hint 2
Extend the current part's end to the last occurrence of each letter you meet; cut when i reaches it.
How to solve Partition Labels
A part can only end where every letter inside it has finished for good. So precompute the last index of each letter, then sweep: the current part must stretch at least to the last occurrence of every letter met so far. The moment the walking index catches up with that frontier, the part is closed.
Approach
- Record the last index at which each letter appears.
- Track
start(where the current part began) andend(how far it must stretch). - For each index
i, extendend = max(end, last[s[i]]). - When
i == end, no letter inside can appear later — cut here, record the lengthend - start + 1, and setstart = i + 1. - The recorded lengths are the answer.
Why it works
Cutting at the earliest legal point is what maximises the number of parts. The invariant is that end is the smallest index at which the current part could legally close, given the letters seen so far; closing any earlier would strand a letter across two parts. Since every cut is taken as early as the constraints permit, no alternative partition can produce more parts — and the greedy choice never blocks a later one, because the remaining suffix is an independent instance of the same problem.
Complexity
- Time —
O(n) - Space —
O(1) — the table holds at most 26 letters
Pitfalls
endmust be a running maximum, not just the last occurrence of the current character.- The part length is
end - start + 1; forgetting the+1yields lengths one short. - Reset
starttoi + 1right after a cut. - Build the last-occurrence table in a separate first pass — you cannot know a letter's final position while still scanning.
Reference solution
Python
from typing import List
def partitionLabels(s: str) -> List[int]:
last = {ch: i for i, ch in enumerate(s)}
out = []
start = 0
end = 0
for i, ch in enumerate(s):
end = max(end, last[ch])
if i == end:
out.append(end - start + 1)
start = i + 1
return outJava
public static int[] partitionLabels(String s) {
int[] last = new int[128];
for (int i = 0; i < s.length(); i++) last[s.charAt(i)] = i;
List<Integer> parts = new ArrayList<>();
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
if (last[s.charAt(i)] > end) end = last[s.charAt(i)];
if (i == end) {
parts.add(end - start + 1);
start = i + 1;
}
}
int[] out = new int[parts.size()];
for (int i = 0; i < parts.size(); i++) out[i] = parts.get(i);
return out;
}C++
vector<int> partitionLabels(string s) {
int last[128];
for (int i = 0; i < 128; i++) last[i] = -1;
for (int i = 0; i < (int) s.size(); i++) last[(int) s[i]] = i;
vector<int> out;
int start = 0, end = 0;
for (int i = 0; i < (int) s.size(); i++) {
if (last[(int) s[i]] > end) end = last[(int) s[i]];
if (i == end) {
out.push_back(end - start + 1);
start = i + 1;
}
}
return out;
}JavaScript
var partitionLabels = function(s) {
const last = new Map();
for (let i = 0; i < s.length; i++) last.set(s[i], i);
const out = [];
let start = 0, end = 0;
for (let i = 0; i < s.length; i++) {
end = Math.max(end, last.get(s[i]));
if (i === end) {
out.push(end - start + 1);
start = i + 1;
}
}
return out;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 515 strings problems · the whole catalogue
Learn the technique: Strings · Hashing: Hash Maps and Hash Sets