Brute Force: Expand Window Until Stable
Time O(nΒ²)Space O(1)Start a window at the current position. For every character currently inside the window, find its last occurrence anywhere in the string and grow the window to cover it. Keep doing this until the window stops growing β at that point every letter inside it is fully contained, so it is a valid partition boundary.
class Solution: def partitionLabels(self, s: str) -> list[int]: result = [] i = 0 n = len(s) while i < n: j = i k = i while k <= j: last = s.rindex(s[k], 0, n) j = max(j, last) k += 1 result.append(j - i + 1) i = j + 1 return resultEach rindex call scans up to the full string, and it can be called up to n times per partition, so this is O(nΒ²) in the worst case.
Greedy: Last-Occurrence Map
OptimalTime O(n)Space O(1)Precompute the last index at which each letter appears β one pass, O(n) (bounded by 26 distinct letters in extra space). Then scan left to right, keeping end as the furthest last-occurrence seen among letters encountered so far in the current partition. The moment the current index i reaches end, every letter seen since the partition started has already had its final appearance β the partition can close right there.
class Solution: def partitionLabels(self, s: str) -> list[int]: last = {c: i for i, c in enumerate(s)} result = [] start = end = 0 for i, c in enumerate(s): end = max(end, last[c]) if i == end: result.append(end - start + 1) start = i + 1 return resultTracing s = "eccbbbbdec" (last occurrences: eβ8, cβ9, bβ6, dβ7):
e last appears at index 8. end = max(0, 8) = 8.
Why itβs correct: a partition boundary is only ever valid at a point where no letter seen so far reappears later β and end is precisely tracking the earliest such point, since it is continuously pulled forward by every letterβs true last occurrence. Closing the partition the instant i == end produces the smallest valid partition starting there, and taking the smallest valid partition at every step is exactly what maximizes the total number of partitions β waiting longer than necessary could only merge two valid partitions into one. Complexity: two linear passes β O(n) time; extra space is O(1) since the last-occurrence map has at most 26 entries.