First pass: record the last occurrence of each character.
Second pass: greedily extend each partition. Start a partition, track the furthest last occurrence of any character seen. When you reach that point, the partition ends.
Key insight: a partition must include all occurrences of its characters. The end is the max last occurrence of characters in the current partition.