1. 程式人生 > 實用技巧 >leetcode hot 100-56. 合併區間

leetcode hot 100-56. 合併區間

56. 合併區間

給出一個區間的集合,請合併所有重疊的區間。

示例 1:

輸入: intervals = [[1,3],[2,6],[8,10],[15,18]]
輸出: [[1,6],[8,10],[15,18]]
解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合併為 [1,6].

示例2:

輸入: intervals = [[1,4],[4,5]]
輸出: [[1,5]]
解釋: 區間 [1,4] 和 [4,5] 可被視為重疊區間。
注意:輸入型別已於2019年4月15日更改。 請重置預設程式碼定義以獲取新方法簽名。

提示:

intervals[i][0] <= intervals[i][1]

思路:

先將二維陣列中的所有子區間按左邊界從小到大排序。

然後遍歷所有的子區間,維護兩個數字,分別是當前合併區間的左邊界和右邊界,每次遍歷時,判斷當前合併的右邊界是否小於下個小區間的左邊界,如果小於的話,說明當前合併區間和下個小區間沒有交集,將當前的左右邊界作為一個區間的左右邊界存入結果集中,並重置下個合併區間的左右邊界為下個小區間的左右邊界;如果當前合併區間的右邊界大於等於下個小區間的左邊界,說明當前合併區間和下個小區間有交集,把合併區間的右邊界更新為 下個小區間的右邊界和當前合併區間右邊界中的較大值,從而讓合併區間擴張。

最後還需要再將合併區間的左右邊界新增到結果集中一次,因為迴圈中沒有把最後一個合併區間新增到結果集中。

 1 class Solution {
 2     public int[][] merge(int[][] intervals) {
 3         if(intervals == null || intervals.length == 0){
 4             return new int[0][0];
 5         }
 6         // 將所有的區間按左區間大小從小到大排序
 7         Arrays.sort(intervals, new Comparator<int[]>(){
 8             public int compare(int
[] a, int[] b){ 9 return a[0] - b[0]; 10 } 11 }); 12 int leftBorder = intervals[0][0], rightBorder = intervals[0][1]; 13 int len = intervals.length; 14 ArrayList<int[]> res = new ArrayList<>(); 15 for(int i = 1; i < len; i++){ 16 if(rightBorder < intervals[i][0]){ // 說明不可能和下個集合有交集 17 //System.out.println(leftBorder + " " + rightBorder); 18 res.add(new int[]{leftBorder, rightBorder}); 19 leftBorder = intervals[i][0]; 20 rightBorder = intervals[i][1]; 21 }else{ 22 rightBorder = Math.max(rightBorder, intervals[i][1]); // 說明有交集 23 } 24 } 25 res.add(new int[]{leftBorder, rightBorder}); 26 return res.toArray(new int[res.size()][2]); 27 } 28 }

leetcode執行用時:7 ms > 90.82%, 記憶體消耗:41 MB > 92.54%

複雜度分析:

時間複雜度:O(nlogn), n 為陣列長度,時間花費主要分為兩部分,一部分是排序,時間複雜度為O(nlogn), 接下來一次遍歷的時間花費為O(n)。

空間複雜度:O(1), 如果不算上 res 這個結果列表的空間開銷的話,那空間複雜度就是O(1)