问题描述(不计算右边界)
小明想发明一台打点计数器,这个计数器有这样的一个功能
- 它可以接收一个递增的数据范围(形如[3, 9]),其中第一个数字代表起始,第二个数字代表结束
- 这个数据范围中包含几个数字,打点计数器就会打几个点
- 在传入的多组数据范围中,如果出现了范围的重复,机器则不会重复打点 你可以帮助小明算一算,在不同的情况下,计数器会打出几个点么?
输入格式
一个二维数组
输出格式
一个整数,表达在输入是这个数组的情况下,计数器打出的点数
输入样例(1)
[ [1,4], [7, 10], [3, 5] ]
输出样例(1)
7
输入样例(2)
[ [1,2], [6, 10], [11, 15] ]
输出样例(2)
9
数据范围
- 数字范围 [-10^9, 10^9],数组长度 < 2^16
编码流程
理解题目
MarsCode
01 为什么输入样例1,会输出7
对于输入样例 1 [[1,4], [7, 10], [3, 5]]
,我们来分析一下。
第一个范围 [1, 4]
包含数字 1、2、3、4,一共 4 个数字。
第二个范围 [7, 10]
包含数字 7、8、9、10,一共 4 个数字。
第三个范围 [3, 5]
包含数字 3、4、5,但是 3、4 已经在第一个范围中出现过了,所以只计算 5,增加 1 个数字。
综上,总共的点数就是 4 + 4 + 1 = 7 。您明白了吗?
02 4+4+1难道不是等于9嘛?
不是的,4 + 4 + 1 = 9 是计算错误,正确的计算应该是 4 + 4 + 1 = 8 + 1 = 9 。但在这个题目中,第三个范围 [3, 5]
中的 3 和 4 已经在第一个范围 [1, 4]
中出现过了,所以只增加了 1 个新数字 5 ,因此总数是 4 + 4 + 1 = 7 。您理解了吗?
chatgpt
这个问题可以理解为计算多个区间的并集所覆盖的数字个数。
问题拆解:
- 区间合并:首先,我们会输入一系列区间。对于这些区间,有的区间可能会互相重叠,因此我们需要将重叠的区间合并,以避免重复计算打点数。
- 点数计算:在合并后的区间中,计算每个合并后区间的长度,所有长度之和就是最终的打点数。
解题步骤:
- 输入解析:我们接收一个二维数组,每个子数组表示一个区间
[start, end]
。 - 排序区间:首先根据每个区间的起点
start
进行排序。如果起点相同,按照终点end
排序。 - 合并区间:依次遍历排序后的区间,判断是否与上一个区间重叠。如果重叠,则合并区间;否则将当前区间计入非重叠的结果中。
- 计算点数:对于每个非重叠的区间,计算其长度
(end - start + 1)
,然后累加所有区间的长度。
示例分析:
输入样例(1):
[
[1,4],
[7, 10],
[3, 5]
]
- 对区间进行排序,得到:
[ [1,4], [3, 5], [7, 10] ]
- 合并区间:
- 第一个区间
[1, 4]
与第二个区间[3, 5]
重叠,合并为[1, 5]
。 - 第三个区间
[7, 10]
不与前面的区间重叠。 - 合并后的区间是:
[[1, 5], [7, 10]]
。
- 第一个区间
- 计算点数:
[1, 5]
的点数为 5。[7, 10]
的点数为 4。- 总点数为
5 + 4 = 9
。
输入样例(2):
[
[1,2],
[6, 10],
[11, 15]
]
- 对区间排序后,区间本身已经是有序且没有重叠的。
- 合并结果为:
[[1, 2], [6, 10], [11, 15]]
。
- 合并结果为:
- 计算点数:
[1, 2]
的点数为 2。[6, 10]
的点数为 5。[11, 15]
的点数为 5。- 总点数为
2 + 5 + 5 = 12
。
总结:
- 排序区间。
- 合并重叠区间。
- 计算合并后的区间的总长度,输出结果。
你是否对这个思路有疑问,或者需要进一步的解释呢?
代码
#include <iostream>
#include <vector>
int solution(std::vector<std::vector<int>> inputArray) {
// Please write your code here
std::vector<int> end;
for (int i = 0; i < inputArray.size(); i++) {
int min = inputArray[i][0];
int max = inputArray[i][inputArray[i].size()-1];
for (int j = min; j < max; j++) {
bool T = true;
for (int k = 0; k < end.size(); k++) {
if (end[k] == j) {
T = false;
}
}
if (T) {
end.push_back(j);
}
}
}
return end.size();
}
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) == 7) << std::endl;
std::cout << (solution(testArray2) == 9) << std::endl;
return 0;
}