763. 划分字母区间
题目描述
给你一个字符串s
。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。
注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s
。
返回一个表示每个字符串片段的长度的列表。
题目理解
首先我们要搞清楚几点关键信息
- 同一个字母第一次出现的下标和最后一次出现的下标必须出现在同一个片段里
- 我们要尽可能使片段多,就是使用贪心的思想,使得每个片段是一个最小的闭集,即每个片段刚刚好包括了片段内第一个出现的字符和最后一个出现的字符。
- 对于每个访问到的字母c得到当前字符最后一次出现的下标位置
endc
,那么当前片段结束的下标end
一定大于endc
,如果字符下标indexc=end
那么这个片段最小
伪代码
1. 初始化每个字母与他最后一次出现的下标位置的哈希表
2. 遍历字符串,初始化end = -1
1. if endc > end
end = endc
if indexc = end
push end
end = -1
代码
class Solution {
private:
unordered_map<char, int> findend;
public:
vector<int> partitionLabels(string s) {
vector<int> ret;
for(int i = 0; i < s.length(); i++){
findend[s[i]] = i;
}
int end = -1;
for(int i = 0; i < s.length(); i++){
int endc = findend[s[i]];
if(endc > end)
end = endc;
if(i == end){
ret.push_back(end+1);//结果的下标是从1开始的不是0
end = -1;
}
}
for(int i = ret.size()-1; i > 0; i--){
ret[i] = ret[i] - ret[i-1];
}
return ret;
}
};