AI刷题 70.打点计数器的区间合并 | 豆包MarsCode AI刷题

60 阅读2分钟

70.打点计数器的区间合并

问题描述

小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。

例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。


1.思路

1.以区间左端点为关键字做快排
2.判断区间关系

若i区间左端点小于等于已存结尾,则i区间与前面区间相交,合并i区间 若i区间左端点大于已存结尾,则i区间与前面区间不相交,将前面区间提取到res数组中,并将起点重设为i区间左端点

3.计算打点数

遍历合并后的区间数组,计算每个区间的长度:`length = ed - st + 1`,累加得到总数字数

2.注意事项

1.初始化

初始化区间起点st和终点ed为一个极小值(例如-2e9),表示当前没有处理区间。 如果输入为空,则直接返回结果为0

2.边界情况

如果只有一个区间,直接返回该区间的数字数量。 如果所有区间互不重叠,结果就是各区间长度的总和。

3.复杂度

1.时间复杂度

将输入的区间按左端点排序,复杂度为 O(nlogn),其中 n 是区间的数量,并且这是最大时间复杂度,因此,时间复杂度为O(nlogn)

2.空间复杂度

存储输入区间和合并后的结果区间,需要额外的 O(n) 空间。 排序操作可能使用额外的栈空间(递归深度),最坏情况为 O(log⁡n)

综合空间复杂度为:O(n)

4.代码实现

#include<bits/stdc++.h>

using namespace std;

typedef pair<int,int> PII;

int solution(std::vector<std::vector<int>> inputArray) {
    // Please write your code here
    int st=-2e9,ed=-2e9;
    vector<PII> segs;
    vector<PII> res;
    int cnt=0;
    for(int i=0;i<inputArray.size();i++){
        segs.push_back({inputArray[i][0],inputArray[i][1]});
    }
    sort(segs.begin(),segs.end());
    for(auto item:segs){
        if(ed<item.first){
            if(st!=-2e9) res.push_back({st,ed});
            st=item.first;
            ed=item.second;
        }else{
            ed=max(ed,item.second);
        }
    }
    if(st!=-2e9) res.push_back({st,ed});
    for(int i=0;i<res.size();i++){
        cnt+=(res[i].second-res[i].first+1);
    }
    return cnt;
}

int main() {
    //  You can add more test cases here
    std::vector<std::vector<int>> testArray1 = {{1, 4}, {7, 10}, {3, 5}};
    std::vector<std::vector<int>> testArray2 = {{1, 2}, {6, 10}, {11, 15}};

    std::cout << (solution(testArray1) == 9) << std::endl;
    std::cout << (solution(testArray2) == 12) << std::endl;

    return 0;
}