zoukankan      html  css  js  c++  java
  • 715. Range Module

    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 queryRange in a single test case is at most 5000.
    • The total number of calls to removeRange in a single test case is at most 1000.
     

    Approach #1: C++. [Using Vector]

    class RangeModule {
    public:
        RangeModule() {
            
        }
        
        void addRange(int left, int right) {
            vector<pair<int, int>> new_ranges;
            bool inserted = false;
            
            for (const auto& it : ranges_) {
                if (it.first > right && !inserted) {
                    new_ranges.emplace_back(left, right);
                    inserted = true;
                }
                if (it.first > right || it.second < left) {
                    new_ranges.push_back(it);
                } else {
                    left = min(left, it.first);
                    right = max(right, it.second);
                }
            }
            if (!inserted) new_ranges.emplace_back(left, right);
            ranges_.swap(new_ranges);
        }
        
        bool queryRange(int left, int right) {
            int l = 0;
            int r = ranges_.size() - 1;
            while (l <= r) {
                int mid = (l + r) / 2;
                if (ranges_[mid].first <= left && ranges_[mid].second >= right) 
                    return true;
                else if (ranges_[mid].first > right) {
                    r = mid - 1;
                } else {
                    l = mid + 1;
                }
            }
            return false;
        }
        
        void removeRange(int left, int right) {
            vector<pair<int, int>> new_ranges;
            for (const auto& it : ranges_) {
                if (it.second <= left || it.first >= right) {
                    new_ranges.emplace_back(it);
                } else {
                    if (it.first < left) 
                        new_ranges.emplace_back(it.first, left);
                    if (it.second > right)
                        new_ranges.emplace_back(right, it.second);
                }
            }
            ranges_.swap(new_ranges);
        }
        
    private:
        vector<pair<int, int>> ranges_;
    };
    
    /**
     * 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);
     */
    

      

    there are some notes about STL.

    1. the difference between emplace_back and push_back.

    2. emplace vs insert.

    3. the method of swap in vector.

    Approach #2: C++. [map]

    class RangeModule {
    public:
        RangeModule() {
            
        }
        
        void addRange(int left, int right) {
            IT l, r;
            getOverLapRanges(left, right, l, r);
            
            if (l != r) {
                auto last = r; last--;
                left = min(left, l->first);
                right = max(right, last->second);
                ranges_.erase(l, r);
            }
            ranges_[left] = right;
        }
        
        bool queryRange(int left, int right) {
            IT l, r;
            getOverLapRanges(left, right, l, r);
            if (l == r) return false;
            return l->first <= left && l->second >= right;
        }
        
        void removeRange(int left, int right) {
            IT l, r;
            getOverLapRanges(left, right, l, r);
            if (l == r) return ;
            auto last = r; last--;
            int start = min(left, l->first);
            int end = max(right, last->second);
            ranges_.erase(l, r);
            if (start < left) ranges_[start] = left;
            if (end > right) ranges_[right] = end;
        }
        
    private:
        typedef map<int, int>::iterator IT;
        map<int, int> ranges_;
        void getOverLapRanges(int left, int right, IT& l, IT& r) {
            l = ranges_.upper_bound(left);
            r = ranges_.upper_bound(right);
            
            // judge the left is the leftmost interval?
            if (l != ranges_.begin()) {
                if ((--l)->second < left) l++;
            }
        }
    };
    
    /**
     * 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);
     */
    

      

    Notes:

    c++::map.erase().

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    selenium中PO模式(Page Object Model)小结
    Selenium webdriver中的xpath定位
    使用cookie实现自动化测试中的自动登录
    Cookie、Session实现“记住登录状态”的原理
    关于移动端文字无法垂直居中(或line-height不起作用)的问题的解决方案(网摘)
    nginx+thinkphp pathinfo模式配置
    ThinkPHP5 安装自定义模块
    腾讯云ubuntu memcached 安装
    腾讯云centos+nginx+nodejs proxy代理配置
    阿里云nginx+thinkphp环境运行会直接下载php文件的问题。
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10049036.html
Copyright © 2011-2022 走看看