352. 将数据流变为多个不相交区间 pair 下的 lower_bound()

352. 将数据流变为多个不相交区间 pair 下的 lower_bound()_第1张图片
352. 将数据流变为多个不相交区间 pair 下的 lower_bound()_第2张图片

可以用multimap或者 multiset去维护有序空间,这里用multiset,里面设置为pair, 用来存放内部区间的左右两个端点。加入两个哨兵节点
每次插入的时候使用upper_bound找到第一个大于插入的数的迭代器位置:
auto l = S.upper_bound({x, -1e8});
注意这里S是mutiset的 一个对象,里面排序的规则是先用first排序后在用second排序,也就是说当first相等时,second小的排在前面,这里第二个second用一个最小的数值,正好找到第一个大于等于他的迭代器,–l就是第一个小于等于他的迭代器。
分三种情况讨论, 见代码

注意define 在 class以外, 关于迭代器的first和second,这两种等同:(*l).first <=====> l->first

code

#define a first 
#define b second

class SummaryRanges {
public:
    typedef pair<int,int> PII;
    multiset<PII>S;
    SummaryRanges() {
        S.insert({-1e8, -1e8});
        S.insert({1e8, 1e8});
    }
    
    void addNum(int x) {
        auto l = S.upper_bound({x, -1e8});
        auto r = l;
        --l;
        if ((*l).b + 1 == x && x == (*r).a - 1) {
            S.insert({(*l).a, (*r).b});
            S.erase(l);
            S.erase(r); //此时还是指向l和r的迭代器
        }
        else if ((*l).b + 1 == x) {
            S.insert({(*l).a, x});
            S.erase(l);
        }
        else if (x == (*r).a - 1) {
            S.insert({x, (*r).b});
            S.erase(r);
        }
        else if ((*l).b + 1 < x && (*r).a - 1 > x) S.insert({x, x});
    }
    
    vector<vector<int>> getIntervals() {
        vector<vector<int>> res;
        for (auto s : S) {
            if (s.a == -1e8 || s.a == 1e8) continue;
            res.push_back({s.a, s.b});
        }
        return res;
    }
};

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges* obj = new SummaryRanges();
 * obj->addNum(val);
 * vector> param_2 = obj->getIntervals();
 */

你可能感兴趣的:(Leetcode思考与技巧题,c++,算法,动态规划)