leetcode hot 100-56. 合併區間
阿新 • • 發佈:2020-10-27
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)