貪心演算法:合併區間
阿新 • • 發佈:2021-06-11
56. 合併區間
以陣列intervals
表示若干個區間的集合,其中單個區間為intervals[i] = [starti, endi]
。請你合併所有重疊的區間,並返回一個不重疊的區間陣列,該陣列需恰好覆蓋輸入中的所有區間。
輸入:intervals = [[1,3],[2,6],[8,10],[15,18]]
輸出:[[1,6],[8,10],[15,18]]
解釋:區間 [1,3] 和 [2,6] 重疊, 將它們合併為 [1,6].
輸入:intervals = [[1,4],[4,5]]
輸出:[[1,5]]
解釋:區間 [1,4] 和 [4,5] 可被視為重疊區間。
思路
按照左邊界從小到大排序之後,如果 intervals[i][0] < intervals[i - 1][1] 即intervals[i]左邊界 < intervals[i - 1]右邊界,則一定有重複,因為intervals[i]的左邊界一定是大於等於intervals[i - 1]的左邊界。
用合併區間後左邊界和右邊界,作為一個新的區間,加入到result數組裡。如果沒有合併就把原區間加入到result陣列。
程式碼
class Solution { public int[][] merge(int[][] intervals) { Arrays.sort(intervals, new Comparator<int[]>() { //左邊界升序排列 public int compare(int[] point1, int[] point2) { if (point1[0] > point2[0]) { return 1; } else if (point1[0] < point2[0]) { return -1; } else { return 0; } } }); boolean flag = false; // 標記最後一個區間有沒有合併 int length = intervals.length; List<int[]> ans = new ArrayList<int[]>(); for (int i = 1; i < length; i++) { int start = intervals[i - 1][0]; // 初始為i-1區間的左邊界 int end = intervals[i - 1][1]; // 初始i-1區間的右邊界 while (i < length && intervals[i][0] <= end) { // 合併區間 end = Math.max(end, intervals[i][1]); // 不斷更新右區間 if (i == length - 1) flag = true; // 最後一個區間也合併了 i++; // 繼續合併下一個區間 } // start和end是表示intervals[i - 1]的左邊界右邊界,所以最優intervals[i]區間是否合併了要標記一下 ans.add(new int[]{start, end}); } // 如果最後一個區間沒有合併,將其加入result if (flag == false) { ans.add(new int[]{intervals[length - 1][0], intervals[length - 1][1]}); } return ans.toArray(new int[ans.size()][]); } }