Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.
Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].
Example 2:
Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.
解答
方法一
首先我們先來看一個新的元素,如果要加入到原本的矩陣中,會有幾種情況:
假設原本已有的元素為:[[1, 6], [8, 12], [15, 19]]
新加入的元素為 [5, 9]-左端點及右端點分別在不同的節點
合併完的矩陣為:[[1, 12], [15, 19]]
=> 這種情況會將原有的 [1, 6], [8, 12] 刪除,並加入 [1, 12] 到矩陣裡
新加入的元素為 [5, 7]-左端點有對應節點,右端點沒有
合併完的矩陣為:[[1, 7], [8, 12], [15, 19]]
=> 將原有的 [1, 6] 刪除,,並加入 [1, 7] 到矩陣裡
新加入的元素為 [7, 9]-右端點有對應節點,左端點沒有
合併完的矩陣為:[[1, 6], [7, 12], [15, 19]]
=> 將原有的 [8, 12] 刪除,,並加入 [7, 12] 到矩陣裡
新加入的元素為 [9, 10]-左端點及右端點都在同一個節點
合併完的矩陣為:[[1, 6], [8, 12], [15, 19]]
=> 原有矩陣不需要處理
新加入的元素為 [20, 23]-左端點及右端點都不在原有的節點裡
合併完的矩陣為:[[1, 6], [8, 12], [15, 19], [20, 23]]
=> 將新加入的元素直接加進原有矩陣
新加入的元素為 [1, 100]-左端點及右端點把原有的節點覆蓋了
合併完的矩陣為:[[1, 100]]
=> 根據新加入元素的左右端點,判斷原有矩陣中哪些被覆蓋的元素需要被刪除
列出這六種可能的情況後接著就可以把這些狀況轉換為程式碼了
Runtime: 416 ms Beats 5.01% of users with JavaScript
Memory: 59.19 MB Beats 48.59% of users with JavaScript
時間複雜度: O(n^2)
要先遍歷一次 原有的矩陣 (intervals),然後又要遍歷 merge 過後的矩陣 (ans)
空間複雜度: O(n)
ans 拿來儲存答案
方法二
可以看到方法一需要列出所有可能的六種情況,接著判斷新加入的元素與每個原有節點之間的關係,這樣寫出一堆 if else 非常的複雜而且也容易出錯
在方法一的過程中,我們需要判斷新加入的元素其左、右端點分別在哪個既有節點上,所以需要去遍歷 ans 矩陣,換個方式想,如果一開始就先將矩陣排序好,當把新加入的元素加進來時,只需要判斷其左、右端點跟原有矩陣的最後一個節點之間的關係就好了,如果是這樣的話總共會有以下三種情況:
假設原本已有的元素為:[[1, 6]]
新加入的元素為 [7, 12]-新加入元素的左端點比原有元素的右端點大
合併完的矩陣為:[[1, 6], [7, 12]]
新加入的元素為 [6, 12]-新加入元素的左端點跟原有元素的右端點一樣大
合併完的矩陣為:[[1, 12]]
新加入的元素為 [3, 7]-新加入元素的右端點比原有元素的右端點大
合併完的矩陣為:[[1, 7]]
新加入的元素為 [2, 3]-新加入的元素被囊括在原有的元素裡 (剩下的情況)
合併完的矩陣為:[[1, 6]]
Runtime: 99 ms Beats 49.59% of users with JavaScript
Memory: 58.58 MB Beats 63.93% of users with JavaScript