763. 划分字母区间
字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。
示例:
输入:S = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca", "defegde", "hijhklij"。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 的划分是错误的,因为划分的片段数较少。
分析:
这道题要是没做过,实在是很难想出来怎么划分。 我们首先要存储每个字母最后一次出现的位置,然后采用一个 当前指针 ,当前指针保存着目前出现的最远的那个字母,如果 当前指针的值 == 最远距离,那么之前出现过的字母就可以划分在一起。
class Solution {
public:
vector<int> partitionLabels(string s) {
int farIndex[128] = {0};
for (int i = 0; i < s.length(); ++i) {
farIndex[s[i]] = i;
}
int curIndex = 0, preIndex = 0;
vector<int> ans;
for (int i = 0; i < s.length(); ++i) {
curIndex = max(curIndex, farIndex[s[i]]);
if (i == curIndex) {
ans.push_back(curIndex-preIndex+1);
preIndex = curIndex+1;
}
}
return ans;
}
};
56. 合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
class Solution {
public:
static bool cmp(vector<int>& a, vector<int>& b) {
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), cmp);
if (intervals.size() == 0) return {};
int left = intervals[0][0], right = intervals[0][1];
vector<vector<int>> ans;
for (int i = 1; i < intervals.size(); ++i) {
if (intervals[i][0] > right) {
ans.push_back({left, right});
left = intervals[i][0];
right = intervals[i][1];
} else {
left = min(left, intervals[i][0]);
right = max(right, intervals[i][1]);
}
}
ans.push_back({left, right});
return ans;
}
};