算法训练营第三十六天||● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间

● 435. 无重叠区间

解法1:

本题其实和452.用最少数量的箭引爆气球 (opens new window)非常像,弓箭的数量就相当于是非交叉区间的数量,只要把弓箭那道题目代码里射爆气球的判断条件加个等号(认为[0,1][1,2]不是相邻区间),然后用总区间数减去弓箭数量 就是要移除的区间数量了。

class Solution {
public:
    static bool cmd(vector& v1,vector& v2){
        return v1[0]>& intervals) {
        sort(intervals.begin(),intervals.end(),cmd);
        int result = 1;
        for(int i = 1;i= intervals[i-1][1]){
                result++;
            }else{
                intervals[i][1] = min(intervals[i][1],intervals[i-1][1]);
            }
        }
        return  intervals.size() - result;
    }
};

解法二:

按左边界排序,然后记录重叠数量

class Solution {
public:
    static bool cmd(vector& v1,vector& v2){
        return v1[0]>& intervals) {
        sort(intervals.begin(),intervals.end(),cmd);
        int count = 0;//记录重叠区间
        for(int i = 1;i

● 763.划分字母区间

一想到分割字符串就想到了回溯,但本题其实不用回溯去暴力搜索。

题目要求同一字母最多出现在一个片段中,那么如何把同一个字母的都圈在同一个区间里呢?

如果没有接触过这种题目的话,还挺有难度的。

在遍历的过程中相当于是要找每一个字母的边界,如果找到之前遍历过的所有字母的最远边界,说明这个边界就是分割点了。此时前面出现过所有字母,最远也就到这个边界了。

可以分为如下两步:

  • 统计每一个字符最后出现的位置
  • 从头遍历字符,并更新字符的最远出现下标,如果找到字符最远出现位置下标和当前下标相等了,则找到了分割点

如图:

算法训练营第三十六天||● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间_第1张图片

明白原理之后,代码并不复杂,

 

class Solution {
public:
    vector partitionLabels(string s) {
        int hash[27] = {0};// i为字符,hash[i]为字符出现的最后位置
        for(int i = 0;i result;
        for(int i = 0;i

● 56. 合并区间

本题的本质其实还是判断重叠区间问题。

大家如果认真做题的话,话发现和我们刚刚讲过的452. 用最少数量的箭引爆气球 (opens new window)和 435. 无重叠区间 (opens new window)都是一个套路。

这几道题都是判断区间重叠,区别就是判断区间重叠后的逻辑,本题是判断区间重贴后要进行区间合并。

所以一样的套路,先排序,让所有的相邻区间尽可能的重叠在一起,按左边界,或者右边界排序都可以,处理逻辑稍有不同。

按照左边界从小到大排序之后,如果 intervals[i][0] <= intervals[i - 1][1] 即intervals[i]的左边界 <= intervals[i - 1]的右边界,则一定有重叠。(本题相邻区间也算重贴,所以是<=)

这么说有点抽象,看图:(注意图中区间都是按照左边界排序之后了

算法训练营第三十六天||● 435. 无重叠区间 ● 763.划分字母区间 ● 56. 合并区间_第2张图片

知道如何判断重复之后,剩下的就是合并了,如何去模拟合并区间呢?

其实就是用合并区间后左边界和右边界,作为一个新的区间,加入到result数组里就可以了。如果没有合并就把原区间加入到result数组。

 

class Solution {
public:
    static bool cmd(const vector& v1,const vector& v2){
        return v1[0]> merge(vector>& intervals) {
        sort(intervals.begin(),intervals.end(),cmd);
        vector> result;
        result.push_back(intervals[0]);
        for(int i = 1;i

你可能感兴趣的:(代码随想录一刷,算法,数据结构)