问题描述
小M正在设计一台打点计数器,该计数器可以接受多个递增的数字范围,并对这些范围内的每个唯一数字打点。如果多个范围之间有重叠,计数器将合并这些范围并只对每个唯一数字打一次点。小M需要你帮助他计算,在给定的多组数字范围内,计数器会打多少个点。例如,给定三个数字范围 [1, 4], [7, 10], 和 [3, 5],计数器首先将这些范围合并,变成 [1, 5] 和 [7, 10],然后计算这两个范围内共有多少个唯一数字,即从 1 到 5 有 5 个数字,从 7 到 10 有 4 个数字,共打 9 个点。
解题思路
为了解决这个问题,我们可以采用以下步骤:
- 排序:首先,我们需要对输入的区间按照起始点进行排序,以便于后续的合并操作。
- 合并区间:然后,我们遍历排序后的区间,如果当前区间与前一个区间有重叠,则合并这两个区间;否则,将当前区间添加到结果中。
- 计算总数:最后,我们计算合并后区间内的唯一数字总数,即每个区间的长度之和。
代码解析
下面是一个C++语言的实现,我们将逐步解析代码中的每个部分。
#include <algorithm>
#include <iostream>
#include <vector>
// 定义函数solution,接受一个二维向量作为输入,每个内嵌向量代表一个区间
int solution(std::vector<std::vector<int>> inputArray) {
// 1. 对区间按起始点进行排序
std::sort(inputArray.begin(), inputArray.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
return a[0] < b[0];
});
// 2. 合并区间
std::vector<std::vector<int>> mergedIntervals;
for (const auto& interval : inputArray) {
if (mergedIntervals.empty() || mergedIntervals.back()[1] < interval[0]) {
mergedIntervals.push_back(interval);
} else {
mergedIntervals.back()[1] = std::max(mergedIntervals.back()[1], interval[1]);
}
}
// 3. 计算总数
int totalCount = 0;
for (const auto& interval : mergedIntervals) {
totalCount += (interval[1] - interval[0] + 1);
}
return totalCount;
}
int main() {
// 测试用例
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;
}
容器的常用操作和函数详解
在上述代码中,我们主要使用了std::vector容器。以下是这个容器的常用操作和函数的详解:
std::vector:C++标准库中的一个动态数组容器,它提供了丰富的数组操作功能。std::sort:用于对容器中的元素进行排序,这里我们使用了一个lambda表达式来指定排序规则,即按照区间的起始点进行排序。push_back:向vector的末尾添加一个元素。max:用于比较两个元素并返回较大的那个。for循环:用于遍历容器中的每个元素。
示例代码
以下是一些操作的示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<std::vector<int>> intervals = {{1, 3}, {2, 6}, {8, 10}};
// 对区间进行排序
std::sort(intervals.begin(), intervals.end(), [](const std::vector<int>& a, const std::vector<int>& b) {
return a[0] < b[0];
});
// 合并区间
std::vector<std::vector<int>> merged;
for (const auto& interval : intervals) {
if (merged.empty() || merged.back()[1] < interval[0]) {
merged.push_back(interval);
} else {
merged.back()[1] = std::max(merged.back()[1], interval[1]);
}
}
// 输出合并后的区间
for (const auto& interval : merged) {
std::cout << "[" << interval[0] << ", " << interval[1] << "]" << std::endl;
}
return 0;
}