1. 程式人生 > 實用技巧 >[LeetCode] 56. Merge Intervals(合併區間)

[LeetCode] 56. Merge Intervals(合併區間)

Description

Given an arrayof 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

.
給定一組區間 intervalsintervals[i] = [starti, endi]),合併所有重疊的區間,並返回一個沒有重疊的區間,這個區間能正好覆蓋輸入的區間。

Examples

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] overlaps, 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.

Constraints

  • 1 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti<= endi<= 104

Solution

首先,有序的區間方便於合併,所以第一步自然是給區間排序。然後取出第一個區間並遍歷剩餘區間:

  • 如果 end 大於等於遍歷到的區間的 start,更新 end;

  • 否則,將這個區間加入結果集,更新當前的區間。

程式碼如下:

import kotlin.math.max

class Solution {
    fun merge(intervals: Array<IntArray>): Array<IntArray> {
        intervals.sortWith(Comparator { i1, i2 ->
            if (i1[0] != i2[0]) {
                compareValues(i1[0], i2[0])
            } else {
                compareValues(i1[1], i2[1])
            }
        })
        if (intervals.isEmpty()) {
            return arrayOf()
        }
        val result = arrayListOf<IntArray>()
        var (start, end) = intervals[0]
        for (i in 1..intervals.lastIndex) {
            if (end >= intervals[i][0]) {
                end = max(end, intervals[i][1])
            } else {
                result.add(intArrayOf(start, end))
                start = intervals[i][0]
                end = intervals[i][1]
            }
        }
        result.add(intArrayOf(start, end))
        return result.toTypedArray()
    }
}