题目描述:
字符串 S
由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段。返回一个表示每个字符串片段的长度的列表。
示例 1:
输入: S = "ababcbacadefegdehijhklij"
输出: [9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
注意:
S
的长度在[1, 500]
之间。S
只包含小写字母'a'
到'z'
。
思路分析:
思路是双指针求解。由于题目限制了字符类型只有字母的大小写。首先利用一个hash表存储字符串中出现字符的最后出现位置。接下来从头开始遍历字符串,start指针指向开始位置,last指针指向对于当前字符来说可接收的最后的位置,在start+1和last之间进行遍历,若当前字符的最后出现位置大于last,则需要更新last。在start+1和last之间的循环结束后,当前的划分长度即为last-start+1。需要注意start为0的情况,如果当前的res数组中为空,则长度即为last-start,否则为last-start+1。
代码:
1 class Solution { 2 public: 3 vector<int> partitionLabels(string S) { 4 vector<int> res; 5 if(S.size()==0) 6 return res; 7 int hash[256] = {0}; 8 for(int i=0; i<S.length();i++) 9 { 10 hash[S[i]] = i; 11 } 12 int last=0; 13 int start = 0; 14 for(int i=0; i<S.length();) 15 { 16 start = last; 17 if(start>=S.length()) 18 break; 19 last = hash[S[i]]; 20 for(int j=start+1; j<=last; j++) 21 { 22 if(hash[S[j]]<last) 23 continue; 24 last = hash[S[j]]; 25 } 26 if(res.size()==0) 27 res.push_back(last-start+1); 28 else 29 res.push_back(last-start); 30 i = last+1; 31 } 32 return res; 33 } 34 };