Problem description:

A string S of lowercase letters is given. We want to partition this string into as many parts as possible so that each letter appears in at most one part, and return a list of integers representing the size of these parts.

Example 1:
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.
Note:

S will have length in range [1, 500].
S will consist of lowercase letters (‘a’ to ‘z’) only.

Solution:

  1. Use an unordered_map to store the last position of occurred character.
  2. Traverse the array, remember the maximum of last position for every showing character.
  3. If current position is the last position of a character, then make a cut.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution:
def partitionLabels(self, s: str) -> List[int]:
'''
a hashtable to keep the last index of char
traverse the string
when traverse the whole string, need additional var to note current last index
'''
mapping = defaultdict(int)
for i, w in enumerate(s):
mapping[w] = i

res = []
last = 0
start = 0
for i, w in enumerate(s):
last = max(last, mapping[w])
if last == i:
res.append(last-start+1)
start = i+1
return res
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public:
vector<int> partitionLabels(string S) {
unordered_map<char, int> map;
vector<int> res;
for(int i= 0; i< S.length(); i++)
map[S[i]]= i;

int last= 0, start= 0;
for(int i= 0; i< S.length(); i++){
last= max(last, map[S[i]]);
if(i == last){
//find a cutting point where this character will not appear in the folowing string anymore
res.push_back(i- start+1);
start= i+1;
}
}
return res;
}
};

reference:
http://www.cnblogs.com/grandyang/p/8654822.html
https://goo.gl/HRrkCn