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 <vector>
#include <utility>
#include <list>
using namespace std;

int sum_intervals(std::vector<std::pair<int, int>> intervals) {
    list<pair<int,int>> limits,tmp;
    int tmpmin,tmpmax,res=0;
    vector<list<pair<int,int>>::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 <vector>
#include <utility>
#include <unordered_set>

int sum_intervals(std::vector<std::pair<int, int>> intervals) {
  
  std::unordered_set<int> 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 <vector>
#include <utility>

int sum_intervals(std::vector<std::pair<int, int>> 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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,448评论 0 10
  • Introduction What is Bowtie 2? Bowtie 2 is an ultrafast a...
    wzz阅读 5,816评论 0 5
  • “人这一辈子谁还不会遇到点什么事啊。有时候是好事,有时候是坏事。坏事来了就得学会忍受,尤其当你无法改变它...
    可苡_菲菲阅读 758评论 2 7
  • Ruby 中使用 mixin 优雅的解决了 multiple inheritance 问题。在 Java 世界中使...
    lvjian700阅读 3,479评论 0 7
  • 下午四点多决定让自己失恋吧!一路回家的环路车上听着一首Faded想着心事。想了想08年离婚大概用了五个月心不...
    塰謿阅读 408评论 0 0