题目
字符串S
由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = "ababcbacadefegdehijhklij" 输出:[9,7,8] 解释: 划分结果为 "ababcbaca", "defegde", "hijhklij"。 每个字母最多出现在一个片段中。 像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
提示:
- S的长度在[1, 500]之间。
- S只包含小写字母 ‘a’ 到 ‘z’ 。
解题
本题的题目看起来有些模糊,实际上题目的重点就是2个
- 尽可能多的片段
- 同一字母最多出现在一个片段中
方法一
在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了
class Solution { public: vector<int> partitionLabels(string s) { int hash[26];// i为字符,hash[i]为字符出现的最后位置 for(int i=0;i<s.size();i++){ // 统计每一个字符最后出现的位置 hash[s[i]-'a']=i; } vector<int> res; int left=0,right=0; for(int i=0;i<s.size();i++){ right=max(right,hash[s[i]-'a']); // 找到字符出现的最远边界 if(i==right){ res.push_back(right-left+1); left=i+1; } } return res; } };
java
class Solution { List<Integer> res=new LinkedList<>(); public List<Integer> partitionLabels(String s) { int[] mp=new int[26]; for(int i=0;i<s.length();i++){ char c=s.charAt(i); mp[c-'a']=i; } int left=0,right=0; for(int i=0;i<s.length();i++){ right=Math.max(right,mp[s.charAt(i)-'a']); if(i==right){ res.add(right-left+1); left=i+1; } } return res; } }