💡 This approach improves efficiency by leveraging the sorted and disjoint nature of the interval lists, using two pointers to traverse both lists simultaneously.
Intuition
Since both lists are sorted and intervals do not overlap within the same list, we can use two pointers to iterate through both lists and find intersections by advancing the pointer with the smaller interval end.
Algorithm
- Initialize two pointers i and j at 0 for lists A and B respectively.
- While both pointers are within their list bounds, compare intervals A[i] and B[j].
- Find the intersection by taking max of starts and min of ends; if they overlap, add to result.
- Advance the pointer whose interval ends first to find new potential intersections.
💡 This approach avoids unnecessary comparisons by moving pointers smartly based on interval ends.
from typing import List
def intervalIntersection(A: List[List[int]], B: List[List[int]]) -> List[List[int]]:
i, j = 0, 0
result = []
while i < len(A) and j < len(B):
start = max(A[i][0], B[j][0])
end = min(A[i][1], B[j][1])
if start <= end:
result.append([start, end])
if A[i][1] < B[j][1]:
i += 1
else:
j += 1
return result
# Driver code
if __name__ == '__main__':
A = [[0,2],[5,10],[13,23],[24,25]]
B = [[1,5],[8,12],[15,24],[25,26]]
print(intervalIntersection(A, B))
Line Notes
i, j = 0, 0Initialize pointers for both lists
while i < len(A) and j < len(B)Loop until one list is exhausted
start = max(A[i][0], B[j][0])Later start time between current intervals
end = min(A[i][1], B[j][1])Earlier end time between current intervals
if start <= endCheck if intervals overlap
result.append([start, end])Add intersection to result
if A[i][1] < B[j][1]Advance pointer with smaller interval end
i += 1Move pointer i forward
elseOtherwise, move pointer j forward
j += 1Move pointer j forward
import java.util.*;
public class IntervalIntersection {
public static List<int[]> intervalIntersection(int[][] A, int[][] B) {
List<int[]> result = new ArrayList<>();
int i = 0, j = 0;
while (i < A.length && j < B.length) {
int start = Math.max(A[i][0], B[j][0]);
int end = Math.min(A[i][1], B[j][1]);
if (start <= end) {
result.add(new int[]{start, end});
}
if (A[i][1] < B[j][1]) {
i++;
} else {
j++;
}
}
return result;
}
public static void main(String[] args) {
int[][] A = {{0,2},{5,10},{13,23},{24,25}};
int[][] B = {{1,5},{8,12},{15,24},{25,26}};
List<int[]> res = intervalIntersection(A, B);
for (int[] interval : res) {
System.out.println("[" + interval[0] + "," + interval[1] + "]");
}
}
}
Line Notes
int i = 0, j = 0;Initialize pointers for both lists
while (i < A.length && j < B.length)Loop until one list is exhausted
int start = Math.max(A[i][0], B[j][0]);Later start time between current intervals
int end = Math.min(A[i][1], B[j][1]);Earlier end time between current intervals
if (start <= end)Check if intervals overlap
result.add(new int[]{start, end});Add intersection to result
if (A[i][1] < B[j][1])Advance pointer with smaller interval end
i++;Move pointer i forward
elseOtherwise, move pointer j forward
j++;Move pointer j forward
#include <iostream>
#include <vector>
using namespace std;
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()) {
int start = max(A[i][0], B[j][0]);
int end = min(A[i][1], B[j][1]);
if (start <= end) {
result.push_back({start, end});
}
if (A[i][1] < B[j][1]) {
i++;
} else {
j++;
}
}
return result;
}
int main() {
vector<vector<int>> A = {{0,2},{5,10},{13,23},{24,25}};
vector<vector<int>> B = {{1,5},{8,12},{15,24},{25,26}};
vector<vector<int>> res = intervalIntersection(A, B);
for (auto &interval : res) {
cout << "[" << interval[0] << "," << interval[1] << "]\n";
}
return 0;
}
Line Notes
int i = 0, j = 0;Initialize pointers for both lists
while (i < A.size() && j < B.size())Loop until one list is exhausted
int start = max(A[i][0], B[j][0]);Later start time between current intervals
int end = min(A[i][1], B[j][1]);Earlier end time between current intervals
if (start <= end)Check if intervals overlap
result.push_back({start, end});Add intersection to result
if (A[i][1] < B[j][1])Advance pointer with smaller interval end
i++;Move pointer i forward
elseOtherwise, move pointer j forward
j++;Move pointer j forward
function intervalIntersection(A, B) {
let i = 0, j = 0;
const result = [];
while (i < A.length && j < B.length) {
const start = Math.max(A[i][0], B[j][0]);
const end = Math.min(A[i][1], B[j][1]);
if (start <= end) {
result.push([start, end]);
}
if (A[i][1] < B[j][1]) {
i++;
} else {
j++;
}
}
return result;
}
// Test
const A = [[0,2],[5,10],[13,23],[24,25]];
const B = [[1,5],[8,12],[15,24],[25,26]];
console.log(intervalIntersection(A, B));
Line Notes
let i = 0, j = 0;Initialize pointers for both lists
while (i < A.length && j < B.length)Loop until one list is exhausted
const start = Math.max(A[i][0], B[j][0])Later start time between current intervals
const end = Math.min(A[i][1], B[j][1])Earlier end time between current intervals
if (start <= end)Check if intervals overlap
result.push([start, end])Add intersection to result
if (A[i][1] < B[j][1])Advance pointer with smaller interval end
i++Move pointer i forward
elseOtherwise, move pointer j forward
j++Move pointer j forward
TimeO(m + n)
SpaceO(m + n)
Each interval is visited at most once by the pointers, resulting in linear time relative to input size.
💡 For 100 intervals in each list, this means about 200 operations, which is efficient for large inputs.
Interview Verdict: Accepted / Optimal for this problem
This approach is efficient and the best practical solution for this problem.