本文共 2137 字,大约阅读时间需要 7 分钟。
区间问题主要包含两种操作:交集和并集。交集要求找到两个区间列表中同时存在的重叠部分,而并集则要求合并所有重叠的区间。
为了解决区间交集问题,可以使用双指针法。假设输入两个已经排序的区间列表A和B,分别用两个指针i和j指向当前的区间。在每一步中,比较A[i]和B[j]的交集情况。
交集条件:
移动指针:
以下是C++实现:
#includeusing namespace std;vector > intervalIntersection(vector > A, vector > B) { vector > res; int i = 0, j = 0; int lenA = A.size(), lenB = B.size(); while (i < lenA && j < lenB) { int a1 = A[i][0], a2 = A[i][1]; int b1 = B[j][0], b2 = B[j][1]; if (a1 <= b1 && a2 >= b1 && a1 <= b2 && a2 >= b2) { // 计算交集区间 int start = max(a1, b1); int end = min(a2, b2); res.push_back({start, end}); if (a2 < b2) { i++; } else { j++; } } else { // 不存在交集的情况 if (a2 < b1) { i++; } else { j++; } } } return res;}
对于区间的并集,我们可以先按起点排序,然后用双指针法合并相邻重叠的区间。
排序:
合并步骤:
以下是C++实现:
#include#include using namespace std;vector > merge(intervals) { vector > res; sort(intervals.begin(), intervals.end(), [](const vector & a, const vector & b) { return a[0] < b[0]; }); if (intervals.empty() || intervals.size() == 1) { return intervals; } res.push_back(intervals[0]); for (size_t i = 1; i < intervals.size(); ++i) { const vector & current = intervals[i]; const vector & last = res.back(); if (current[0] <= last[1]) { // 重叠的情况,更新终点 if (current[1] > last[1]) { last[1] = current[1]; } } else { // 不重叠,添加新区间 res.push_back(current); } } return res;}
区间问题中,寻找交集和合并都是常见操作。通过双指针法,我们可以高效地解决这些问题。交集处理需仔细比较起点和终点的关系,而合并则依赖于排序后的区间列表。理解这些技巧有助于你在面对类似问题时灵活应对。
转载地址:http://spuiz.baihongyu.com/