Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでコースの開始・終了時刻から受講できる最大コース数を求める方法

この記事では、コースの開始時刻と終了時刻を表す区間リスト [start, end] が与えられたときに、受講できるコースの最大数を求めるPythonプログラムを解説します。条件として、同時に受講できるのは1つのコースのみで、次のコースの開始時刻は直前に受講したコースの終了時刻より後である必要があります。

例えば、入力が times = [[3, 6], [6, 9], [7, 8], [9, 11]] の場合、出力は 3 となります。これは [3, 6][7, 8][9, 11] の3つのコースを受講できるためです。

解決の手順

この問題は貪欲法(グリーディ法)を使うことで効率的に解けます。手順は以下の通りです。

  1. コースを終了時刻の早い順にソートする
  2. カウンター counter を 0、変数 end を -1 で初期化する
  3. times の各要素について以下を繰り返す:
    • そのコースの開始時刻 times[i][0]end より大きい場合、counter を1増やし、end をそのコースの終了時刻 times[i][1] に更新する
  4. 最後に counter を返す

なぜこのアルゴリズムが有効か

終了時刻の早い順にソートしておくことで、各ステップで「現時点で選べる中で最も早く終わるコース」を常に選択できます。これにより、後続のコースの選択肢を最大限に残せるため、結果として受講できるコース総数が最大になります。

計算量については、ソートに O(n log n)、走査に O(n) が必要となるため、全体の時間計算量は O(n log n) です。

実装例

class Solution:
   def solve(self, times):
      times.sort(key=lambda x: x[1])

      counter = 0
      end = -1

      for i in range(len(times)):
         if times[i][0] > end:
            counter += 1
            end = times[i][1]
      return counter

ob = Solution()
times = [
   [3, 6],
   [6, 9],
   [7, 8],
   [9, 11]
]
print(ob.solve(times))

入力

[[3, 6], [6, 9], [7, 8], [9, 11]]

出力

3

このように、終了時刻でソートして先頭から貪欲に選んでいくシンプルなアプローチで、区間スケジューリング問題を短いコードで解決できます。面接や競技プログラミングでも頻出のパターンなので、ぜひ覚えておきましょう。

  1. Pythonで素数を見つける3つの方法と実行速度の徹底比較

    はじめに このチュートリアルでは、Pythonで素数を見つけるための複数の手法を取り上げ、それぞれにかかる実行時間を実際に計測して比較します。計測にはPython標準ライブラリのtimeモジュールを使用します。同じ処理でも書き方を少し工夫するだけで実行速度が大きく変わることを、コード例とともに確認していきましょう。 方法1:基本の総当たり法 もっとも一般的な素数判定の方法です。2からn-1までのすべての整数で順番に割り切れるかを調べます。 数値が1以下の場合はFalseを返します(1は素数ではないため)。 ループ中に割り切れる数(約数)が見つかったら、その時点でFalseを返します。 ルー

  2. 【Python入門】3つの数値から最大値を求める方法

    3つの数値 a、b、c が与えられたとき、その中で最も大きい要素(最大値)を見つけるのが今回の課題です。ここでは、Pythonのリストと組み込み関数 max() を使ったシンプルな方法を、初心者向けにわかりやすく解説します。 実行例 入力:a = 2, b = 4, c = 3 出力:4 アルゴリズム ステップ1:ユーザーから3つの数値を入力として受け取る。 ステップ2:3つの数値をリストに格納する。 ステップ3:max() 関数を使ってリスト内の最大値 max(lst) を求める。 ステップ4:最後に最大値を出力する。 サンプルコード def maximum(a, b, c):