贪心算法 part 02
贪心算法
● 435. 无重叠区间
● 763.划分字母区间
● 56. 合并区间
435. 无重叠区间
法1:贪心
/**
* 按照右边界排序,从左向右记录非交叉区间的个数。
* 最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了。
* @param intervals
* @return
*/
//排序
static bool cmp(vector<int>& a, vector<int>& b){
return a[1] < b[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(),intervals.end(),cmp);
if (intervals.size() == 0)return 0;
int ans = 1;
int end = intervals[0][1];//记录不重叠区间的右边界
for (int i = 1; i < intervals.size(); ++i) {
if (end <= intervals[i][0]){
ans++;
end = intervals[i][1];
} else continue;
}
return intervals.size() - ans;
}
763.划分字母区间
763.划分字母区间
法1:贪心
vector<int> partitionLabels(string s) {
//1.统计每一个字符最后出现的位置
//2.从头遍历字符,并更新字符的最远出现下标,
// 如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
int hash[27]= {0};
for (int i = 0; i < s.length(); ++i) {
// if (i > hash[s[i] - 'a'])
//类似自动更新了
hash[s[i] - 'a'] = i;
}
vector<int> ans;
int left = 0;
int right = 0;
for (int i = 0; i < s.length(); ++i) {
//从头遍历字符,并更新字符的最远出现下标,
// 如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点
//并更新字符的最远出现下标
right = max(right, hash[s[i] - 'a']);
if (right == i){//此处记录的是位置
ans.push_back(right - left + 1);
left = right + 1;
}
}
return ans;
}
56. 合并区间
法1:贪心
static bool cmp(vector<int>& a,vector<int>& b){
return a[0] < b[0];
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if (intervals.size() == 0)return vector<vector<int>>(0);
//排序
sort(intervals.begin(),intervals.end(),cmp);
vector<vector<int>> ans;
ans.push_back(intervals[0]);
for (int i = 1; i < intervals.size(); ++i) {
//交叉 不断开继续延拓 更新右边界
if (intervals[i][0] <= ans.back()[1]){
// 合并区间,只更新右边界就好,因为result.back()的左边界一定是最小值,
// 因为我们按照左边界排序的
ans.back()[1] = max(intervals[i][1],ans.back()[1]);
} else{
//不交叉 断开重新开始
ans.push_back(intervals[i]);
}
}
return ans;
}