CodeWar::Sum of Intervals

Write a function called sumIntervals/sum_intervals() that accepts an array of intervals, and returns the sum of all the interval lengths. Overlapping intervals should only be counted once.

Intervals

Intervals are represented by a pair of integers in the form of an array. The first value of the interval will always be less than the second value. Interval example: [1, 5] is an interval from 1 to 5. The length of this interval is 4.

Overlapping Intervals

List containing overlapping intervals:

[
[1,4],
[7, 10],
[3, 5]
]

The sum of the lengths of these intervals is 7. Since [1, 4] and [3, 5] overlap, we can treat the interval as [1, 5], which has a length of 4.

Examples:

sum_intervals( {
{1,2},
{6, 10},
{11, 15}
} ); // => 9

sum_intervals( {
{1,4},
{7, 10},
{3, 5}
} ); // => 7

sum_intervals( {
{1,5},
{10, 20},
{1, 6},
{16, 19},
{5, 11}
} ); // => 19

我的思路是

  1. 创建一个limits容器存储pair
  2. 对输入每一条pair检查是否与limits里的pair有重叠的地方,如果有,记录下位置存入overlap
  3. 将limits里对应的条目删去,在重合的条目中寻找最小的下限和最大的上限,插入limits中
  4. 最后计算intervals

我在自己的ide中运行正常,但是在codewars提交之后在某些情况下出错,code139,是越界之类的问题。
一开始我是用vector来存储limits的,由于涉及到删除元素的问题,特意还用overlap来记录迭代器,循环之后一起删除,经过排除还是发现删除元素后迭代器失效的问题,如上第3步。于是改用list。
这次的经历更深刻的告诉我要注意迭代器失效的问题。

具体代码:

#include 
#include 
#include 
using namespace std;

int sum_intervals(std::vector> intervals) {
    list> limits,tmp;
    int tmpmin,tmpmax,res=0;
    vector>::iterator> overlap;
    if(intervals.size() == 0) return 0;

    for(auto interval : intervals){

       overlap.clear();
       tmp.clear();
       
       for(auto it = limits.begin();it!=limits.end();it++){
            if((interval.first>=(*it).first && interval.first<(*it).second) ||
               (interval.second>(*it).first && interval.second<=(*it).second) ||
               (interval.first<=(*it).first && interval.second>=(*it).second)){
                overlap.push_back(it);
                tmp.push_back(*it);
            }
        }
        tmp.push_back(interval);
        if(overlap.size()!=0){
            for(auto del_it : overlap) {limits.erase(del_it);}
            tmpmin=(*tmp.begin()).first;
            tmpmax=(*tmp.begin()).second;
            for(auto tmp_it = tmp.begin();tmp_it!=tmp.end();tmp_it++){
                if(tmpmin>(*tmp_it).first) tmpmin = (*tmp_it).first;
                if(tmpmax<(*tmp_it).second) tmpmax =(*tmp_it).second;
            }
            limits.push_back(make_pair(tmpmin,tmpmax));
        }
        else limits.push_back(interval);
    }
    
    for (auto limit:limits){
        res+=(limit.second-limit.first);
    }
    return res;
}

·提交之后,欣赏一下其他人的解答:

  1. 使用了set的无重复性,统计区间内的所有整数,最后返回set的size。如果数的范围大的话,浪费内存,将两个数表示的区间,生成了非常多元素的set。
#include 
#include 
#include 

int sum_intervals(std::vector> intervals) {
  
  std::unordered_set ints;
  for (auto interv = intervals.begin(); interv != intervals.end(); ++interv){
    for (int i = interv->first; i < interv->second; i++){
      ints.insert(i);
    }
  }

return ints.size();
}
  1. 先进行了排序,再维护一个max_right。即可计算结果。这个答案比较好。
#include 
#include 

int sum_intervals(std::vector> interavls) {
  sort(interavls.begin(), interavls.end());
  int ret = 0;
  int max_right = interavls[0].first;
  for (auto &i : interavls)
       if (i.second >= max_right) {
           ret += i.second - std::max(max_right, i.first);
           max_right = i.second;
       }
  return ret;
}

你可能感兴趣的:(CodeWar::Sum of Intervals)