leetcode 715. Range Module

6 篇文章 0 订阅
3 篇文章 0 订阅

A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient manner.

 

  • addRange(int left, int right) Adds the half-open interval [left, right), tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval [left, right)that are not already tracked.

 

 

  • queryRange(int left, int right)Returns true if and only if every real number in the interval [left, right) is currently being tracked.

 

 

  • removeRange(int left, int right)Stops tracking every real number currently being tracked in the interval [left, right).

 

Example 1:

addRange(10, 20): null
removeRange(14, 16): null
queryRange(10, 14): true (Every number in [10, 14) is being tracked)
queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked)
queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked, despite the remove operation)

 

Note:

  • A half open interval [left, right)denotes all real numbers left <= x < right.
  • 0 < left < right < 10^9 in all calls to addRange, queryRange, removeRange.
  • The total number of calls to addRange in a single test case is at most 1000.
  • The total number of calls to queryRangein a single test case is at most 5000.
  • The total number of calls to removeRange in a single test case is at most 1000.

解题思路:

解法一:将所有不相交的区间放置到向量中,跟之前的区间的题目Insert IntervalMerge Intervals没有什么不同 。

但是添加区间,删除区间的的时间复杂度就是O(N),查找用二分查找时间复杂度是O(logN),但是超时了;

class RangeModule {
public:
    RangeModule() {
        
    }
    
    void addRange(int left, int right) 
    {
        if(intes.empty()) 
        {
            intes.push_back({left , right}) ;
            return ;
        }
        auto itb = intes.begin() ;
        vector<vector<int>> newintes ;
        while(itb != intes.end() && (*itb)[0] <= right)
        {
            if((*itb)[1] < left) 
            {
                newintes.push_back(*itb) ;
                itb++ ;
                continue ;
            }
            left = min((*itb)[0] , left) ;
            right = max((*itb)[1] , right) ;
            itb++ ;
        }
        newintes.push_back({left , right}) ;
        newintes.insert(newintes.end() , itb , intes.end()) ;
        intes = newintes ;
    }
    
    bool queryRange(int left, int right) 
    {
        int l = 0 , r = intes.size() ;
        while(l < r)
        {
            int mid = l + (r - l)/2 ;
            if(intes[mid][0] <= left && intes[mid][1] >= right) return true ;
            else if(intes[mid][1] <= left) l = mid + 1 ;
            else if(intes[mid][0] >= right) r = mid ;
            else return false ;
        }
        return false ;
    }
    
    void removeRange(int left, int right) 
    {
        vector<vector<int>> newintes ;
        auto itb = intes.begin() ;
        while(itb != intes.end())
        {
            if((*itb)[1] <= left)
            {
                newintes.push_back(*itb) ;
                itb++ ;
                continue ;
            }
            if(right <= (*itb)[1])
            {
                int newleft = right ;
                if(left > (*itb)[0]) newintes.push_back({(*itb)[0] , left }) ;
                if(newleft < (*itb)[1]) newintes.push_back({ max(newleft , (*itb)[0]) , (*itb)[1]}) ;
                itb++ ;
                break ;
            }
            else
            {
                if(left > (*itb)[0]) newintes.push_back({(*itb)[0] , left }) ;
                left = (*itb)[1] ;
                itb++ ;
            }
        }
        newintes.insert(newintes.end() , itb , intes.end() ) ;
        intes = newintes ;
    }
    
private :
    
    vector<vector<int> > intes ;
};

/**
 * Your RangeModule object will be instantiated and called as such:
 * RangeModule* obj = new RangeModule();
 * obj->addRange(left,right);
 * bool param_2 = obj->queryRange(left,right);
 * obj->removeRange(left,right);
 */

解法二:

用orderde map来做,存储[left , right) , m[left] = right ;然后查找m中所有与[left , right)有交集的区间并合并。时间复杂度都为O(logN) ;

class RangeModule {
public:
    RangeModule() {
        
    }
    
    void addRange(int left, int right) 
    {
        pair<int , int> inte = find(left , right) ;
        m[inte.first] = inte.second ;
    }
    
    bool queryRange(int left, int right) 
    {
        auto it = m.upper_bound(left) ;
        return it != m.begin() && (--it)->second >= right ;
    }
    
    void removeRange(int left, int right) 
    {
        pair<int , int> inte = find(left , right) ;
        if(left > inte.first) m[inte.first] = left ;
        if(right < inte.second) m[right] = inte.second ;
    }
    
private :
    
    map<int , int > m ;
    
    pair<int , int> find(int left , int right)
    {
        auto l = m.upper_bound(left) ;
        auto r = m.upper_bound(right) ;
        if(l != m.begin() && (--l)->second < left) ++l;
        if(l == r) return {left , right} ;
        left = min(left , l->first) ;
        right = max(right , (--r)->second) ;
        m.erase(l , ++r) ;
        return {left , right} ;
    }
};

/**
 * Your RangeModule object will be instantiated and called as such:
 * RangeModule* obj = new RangeModule();
 * obj->addRange(left,right);
 * bool param_2 = obj->queryRange(left,right);
 * obj->removeRange(left,right);
 */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值