การหาช่วงตัดของรายการช่วง (Interval List Intersections)
สมมติว่าเรามีสองรายการของช่วงปิด (closed intervals) โดยแต่ละรายการมีช่วงที่ไม่ทับซ้อนกัน (pairwise disjoint) และเรียงลำดับแล้ว เราต้องการหาช่วงตัด (intersection) ของสองรายการช่วงนี้
ช่วงปิด [a, b] หมายถึง a ≤ b คือเซตของจำนวนจริง x ที่ทำให้ a ≤ x ≤ b ช่วงตัดของช่วงปิดสองช่วงจะเป็นเซตของจำนวนจริงที่อาจว่างเปล่าหรือสามารถแทนเป็นช่วงปิดได้
ตัวอย่างเช่น หากอินพุทคือ A = [[0,2],[5,10],[13,23],[24,25]] และ B = [[1,5],[8,12],[15,24],[25,27]] ผลลัพธ์จะเป็น [[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
ขั้นตอนการแก้ปัญหา
- สร้างรายการผลลัพธ์
resกำหนดi := 0และj := 0 - กำหนดฟังก์ชัน
intersect()ที่รับพารามิเตอร์aและb:- ถ้า
a[0] ≤ b[0]และa[1] ≥ b[0]คืนค่าtrue - ถ้า
b[0] ≤ a[0]และb[1] ≥ a[0]คืนค่าtrue - มิฉะนั้นคืนค่า
false
- ถ้า
- วนลูปในขณะที่
i < size of Aและj < size of B:- ถ้า
intersect(A[i], B[j])เป็นจริง:- คำนวณ
temp := [max(A[i][0], B[j][0]), min(A[i][1], B[j][1])] - อัปเดต
A[i][0] := temp[1] + 1,B[j][0] := temp[1] + 1 - ถ้า
A[i][0] > A[i][1]หรือA[i][1] ≤ temp[0]เพิ่มiขึ้น 1 - ถ้า
B[j][0] > B[j][1]หรือB[j][1] ≤ temp[0]เพิ่มjขึ้น 1 - เพิ่ม
tempเข้าresult - ข้ามไปรอบถัดไป (
continue)
- คำนวณ
- ถ้า
A[i][0] > B[j][1]เพิ่มjขึ้น 1 มิฉะนั้นเพิ่มiขึ้น 1
- ถ้า
ตัวอย่างโค้ด C++
class Solution {
public:
vector<vector<int>> intervalIntersection(vector<vector<int>>& A, vector<vector<int>>& B) {
vector<vector<int>> result;
int i = 0, j = 0;
while (i < A.size() && j < B.size()) {
if (intersect(A[i], B[j])) {
vector<int> temp = {max(A[i][0], B[j][0]), min(A[i][1], B[j][1])};
A[i][0] = temp[1] + 1;
B[j][0] = temp[1] + 1;
if (A[i][0] > A[i][1] || A[i][1] <= temp[0]) i++;
if (B[j][0] > B[j][1] || B[j][1] <= temp[0]) j++;
result.push_back(temp);
continue;
}
if (A[i][0] > B[j][1]) j++;
else i++;
}
return result;
}
bool intersect(vector<int>& a, vector<int>& b) {
if (a[0] <= b[0] && a[1] >= b[0]) return true;
if (b[0] <= a[0] && b[1] >= a[0]) return true;
return false;
}
};
อินพุทและเอาต์พุทตัวอย่าง
Input: [[0,2],[5,10],[13,23],[24,25]] [[1,5],[8,12],[15,24],[25,27]]
Output: [[1, 2], [5, 5], [8, 10], [15, 23], [24, 24], [25, 25]]