Swift教室 Swift と競技プログラミングの教室

55. Meeting Rooms

読了目安 約2分

その他 / LeetCode 252 (Easy) — 会議の区間が重ならず全部に出席できるか判定する

この章の目次

問題

LeetCode 252. Meeting Rooms(Easy / カテゴリ: その他)

会議の時刻を並べた配列 intervals が与えられます。 各要素は [開始, 終了] の 2 要素の配列で、[5, 10] は時刻 5 に始まり時刻 10 に終わる会議を表します。

1 人がすべての会議に出席できるか、つまりどの 2 つの会議も時間帯が重ならないかを Bool で返します。 前の会議の終了と同時に次の会議が始まるのは、重なりではありません。

例: [[0, 30], [5, 10], [15, 20]][0, 30][5, 10] が重なるので false です。 [[7, 10], [2, 4]] は重なりがないので true で、空の配列も true です。

この問題は LeetCode Premium 限定です。問題の要点は上の要約の通りです。 無料で読める類題は 56. Merge Intervals で、区間を開始時刻でソートして隣どうしを見る骨組みが共通です。

考え方

ヒント 1

重なりがあるなら、開始時刻順に並べたときの「隣どうし」に必ず現れます。 離れた 2 つだけが重なることはありません。

ヒント 2

開始時刻でソートし、各 i について sorted[i][0] < sorted[i - 1][1] なら重なりです。 1 つも見つからなければ true を返します。

Swift 実装のポイント

  • intervals.sorted { $0[0] < $1[0] } で開始時刻順に並べ替えられます。
  • 要素が 0 個のとき 1..<count1..<0 となり実行時エラーです。guard intervals.count >= 2 else { return true } を先に置きます。
  • 重なりの判定は < です。<= にすると「終了と同時に次が始まる」ケースを誤って重なり扱いします。
模範解答
Swift
class Solution {
    func canAttendMeetings(_ intervals: [[Int]]) -> Bool {
        guard intervals.count >= 2 else { return true }
        let sorted = intervals.sorted { $0[0] < $1[0] }
        for i in 1..<sorted.count {
            if sorted[i][0] < sorted[i - 1][1] {
                return false
            }
        }
        return true
    }
}

計算量: O(n log n)。