题目解析
题目来源
题目分析
我们先来看看最简单的,假如要求分隔字符串,同一字母最多出现在一个片段中
class Solution {
vector<int> ans;
public:
vector<int> partitionLabels(string s) {
// 同一个字母最多出现在一个片段中
std::map<int, std::set<char>> hash;
int len = s.length();
for (int i = 0; i < len; i++) {
char ch = s[i];
int j;
for (j = len - 1; j >= i; --j) { // 从后往前找,找到相等的i
if(ch == s[j]){
break;
}
}
std::string str = s.substr(i, j - i + 1);
printf("%s\r\n", str.c_str());
}
return ans;
}
};
离最终答案只需要把可以重叠的字符串合并成一个字符串就可以了。
那怎么看字符串有没有重叠的部分呢?
- 我们只需要统计每一个字母第一次出现的下标,和最后一次出现的下标,就可以得到每个字母的区间范围
- 然后题目就会转化为LeetCode-56. 合并区间
class Solution {
public:
vector<int> partitionLabels(string s) {
int n = s.size();
std::unordered_map<char, int> m;
for(int i = 0; i < n; i++){
m[s[i]] = i;
}
std::vector<int> res;
int start = 0, last = 0;
for (int i = 0; i < n; ++i) {
last = std::max(last, m[s[i]]); // 当前字符最后一次出现的位置
if(i == last){
res.push_back(last - start + 1);
start = i + 1;
}
}
return res;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:56. 将所有重叠的区间合并到一个区间里面 Merge Intervals | 合并重叠区间:先按照起始位置排序,然后判断区间是否重叠(start[i] < end) ,如果不重叠,那么压入一个新的区间,否则更新右边界 |
leetcode:495. 提莫攻击 teemo-attacking | 合并重叠区间 |
leetcode:763. 划分字母区间,同一字母最多只能出现在一个判断中 | 先求出每一个字母第一次出现的下标和最后一次出现的下标,就可以得到每个字母的区间范围;然后合并重叠的区间;最后,求出每个区间的长度 |
leetcode: 758. 如果s中有子串在word中出现过,那么在s的那个子串的两端添加标签 bold-words-in-string | 先找出所有重叠的区间,然后合并重叠区间,最后原str配合求出来的区间生成一个新str |
Leetcode:252. 一个人是否能参见完所有的会议 meeting-rooms | 本质是判断是否存在重叠区间:将区间按照会议开始时间升序排序;遍历会议,如果下一个会议在前一个会议结束之前就开始了,返回 false。 |
leetcode:253. 至少需要多少间会议室 Meeting Rooms II | 最小堆:先按照开始时间对这些数组进行排序,然后准备一个最小堆,这个最小堆维护的是当前会议之前开始的会议的结束时间。 |