问题描述
小明正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小明需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。
例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
测试样例
样例1:
输入:
inputArray = [[1, 4], [7, 10], [3, 5]]
输出:9
样例2:
输入:
inputArray = [[1, 2], [6, 10], [11, 15]]
输出:12
样例3:
输入:
inputArray = [[1, 3], [2, 6], [8, 10]]
输出:9
问题理解
这道题需要计算多个递增数字范围的唯一数字总数。如果多个范围有重叠,这些范围应该被合并,并且每个唯一数字只计算一次。
代码解析
int solution(std::vector<std::vector<int>> inputArray) {
int count = 0;
//对区间按起始位置进行排序
std::sort(inputArray.begin(), inputArray.end(),
[](std::vector<int> x, std::vector<int> y)->bool{
return x[0] < y[0];
});
int start = inputArray[0][0],
end = inputArray[0][1];
for(int i = 1; i < inputArray.size(); i++) {
if(inputArray[i][0] < end)
end = std::max(inputArray[i][1], end);
else {
count += end - start;
start = inputArray[i][0];
end = inputArray[i][1];
}
}
count += end - start;
return count;
}
- 排序:为了方便合并区间,首先需要对区间按起始位置进行排序。
- 合并区间:遍历排序后的区间,合并重叠的区间。
- 初始化
start和end为第一个区间的起始和结束位置。 - 遍历后续区间,如果当前区间的起始位置小于等于
end,则说明当前区间与之前的区间重叠,更新end为当前区间的结束位置和end的最大值,对区间进行合并。 - 如果当前区间的起始位置大于
end,则说明当前区间与之前的区间不重叠,可以计算之前合并区间的长度,并更新start和end为当前区间的起始和结束位置。 - 处理边界情况,最后再计算一次合并区间的长度,累加到总数中。
- 初始化
复杂度分析
遍历了一次向量,时间复杂度应该是 ,但是由于先对区间进行了排序,所以实际的时间复杂度为 。