那么我们用同样的思路来扩展到需要交集为 m,m > 1 的情况:此时同样首先对 intervals 按照 [s,e] 序对进行升序排序,然后我们需要额外记录每一个区间与最后交集集合中相交的元素(只记录到 m 个为止)。同样我们从最后一个区间往前进行处理,如果该区间与交集集合相交元素个数小于 m 个时,我们从该区间左边界开始往后添加不在交集集合中的元素,并往前进行更新需要更新的区间,重复该过程直至该区间与交集元素集合有 m 个元素相交。到此就可以解决问题了,不过我们也可以来修改排序的规则——我们将区间 [s,e] 序对按照 s 升序,当 s 相同时按照 e 降序来进行排序,这样可以实现在处理与交集集合相交元素个数小于 m 个的区间 [s_i,e_i] 时,保证不足的元素都是在区间的开始部分,即我们可以直接从区间开始部分进行往交集集合中添加元素。
而对于本题来说,我们只需要取 m = 2 的情况即可。
代码
[sol1-Python3]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution: defintersectionSizeTwo(self, intervals: List[List[int]]) -> int: intervals.sort(key=lambda x: (x[0], -x[1])) ans, n, m = 0, len(intervals), 2 vals = [[] for _ inrange(n)] for i inrange(n - 1, -1, -1): j = intervals[i][0] for k inrange(len(vals[i]), m): ans += 1 for p inrange(i - 1, -1, -1): if intervals[p][1] < j: break vals[p].append(j) j += 1 return ans
classSolution { public: voidhelp(vector<vector<int>>& intervals, vector<vector<int>>& temp, int pos, int num){ for (int i = pos; i >= 0; i--) { if (intervals[i][1] < num) { break; } temp[i].push_back(num); } }
intintersectionSizeTwo(vector<vector<int>>& intervals){ int n = intervals.size(); int res = 0; int m = 2; sort(intervals.begin(), intervals.end(), [&](vector<int>& a, vector<int>& b) { if (a[0] == b[0]) { return a[1] > b[1]; } return a[0] < b[0]; }); vector<vector<int>> temp(n); for (int i = n - 1; i >= 0; i--) { for (int j = intervals[i][0], k = temp[i].size(); k < m; j++, k++) { res++; help(intervals, temp, i - 1, j); } } return res; } };
publicclassSolution { publicintIntersectionSizeTwo(int[][] intervals) { int n = intervals.Length; int res = 0; int m = 2; Array.Sort(intervals, (a, b) => { if (a[0] == b[0]) { return b[1] - a[1]; } return a[0] - b[0]; }); IList<int>[] temp = new IList<int>[n]; for (int i = 0; i < n; i++) { temp[i] = new List<int>(); } for (int i = n - 1; i >= 0; i--) { for (int j = intervals[i][0], k = temp[i].Count; k < m; j++, k++) { res++; Help(intervals, temp, i - 1, j); } } return res; }
publicvoidHelp(int[][] intervals, IList<int>[] temp, int pos, int num) { for (int i = pos; i >= 0; i--) { if (intervals[i][1] < num) { break; } temp[i].Add(num); } } }
staticvoidhelp(int** intervals, int** temp, int *colSize, int pos, int num) { for (int i = pos; i >= 0; i --) { if (intervals[i][1] < num) { break; } temp[i][colSize[i]++] = num; } }
intintersectionSizeTwo(int** intervals, int intervalsSize, int* intervalsColSize){ int res = 0; int m = 2; qsort(intervals, intervalsSize, sizeof(int *), cmp); int **temp = (int **)malloc(sizeof(int *) * intervalsSize); for (int i = 0; i < intervalsSize; i++) { temp[i] = (int *)malloc(sizeof(int) * 2); } int *colSize = (int *)malloc(sizeof(int) * intervalsSize); memset(colSize, 0, sizeof(int) * intervalsSize); for (int i = intervalsSize - 1; i >= 0; i --) { for (int j = intervals[i][0], k = colSize[i]; k < m; j++, k++) { res++; help(intervals, temp, colSize, i - 1, j); } } for (int i = 0; i < intervalsSize; i++) { free(temp[i]); } free(colSize); return res; }
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
funcintersectionSizeTwo(intervals [][]int) (ans int) { sort.Slice(intervals, func(i, j int)bool { a, b := intervals[i], intervals[j] return a[0] < b[0] || a[0] == b[0] && a[1] > b[1] }) n, m := len(intervals), 2 vals := make([][]int, n) for i := n - 1; i >= 0; i-- { for j, k := intervals[i][0], len(vals[i]); k < m; k++ { ans++ for p := i - 1; p >= 0 && intervals[p][1] >= j; p-- { vals[p] = append(vals[p], j) } j++ } } return }
var intersectionSizeTwo = function(intervals) { const n = intervals.length; let res = 0; let m = 2; intervals.sort((a, b) => { if (a[0] === b[0]) { return b[1] - a[1]; } return a[0] - b[0]; }); const temp = newArray(n).fill(0); for (let i = 0; i < n; i++) { temp[i] = []; }
consthelp = (intervals, temp, pos, num) => { for (let i = pos; i >= 0; i--) { if (intervals[i][1] < num) { break; } temp[i].push(num); } }
for (let i = n - 1; i >= 0; i--) { for (let j = intervals[i][0], k = temp[i].length; k < m; j++, k++) { res++; help(intervals, temp, i - 1, j); } } return res; };
复杂度分析
时间复杂度:O(n \log n + nm),其中 n 为给定区间集合 intervals 的大小,m 为设置交集大小,本题为 2。
空间复杂度:O(nm),其中 n 为给定区间集合 intervals 的大小,m 为设置交集的大小,本题为 2。主要开销为存储每一个区间与交集集合的相交的元素的开销。