トポロジカルソートで全部の講座を受けられるか調べる

「この​講座の​前に​あの​講座を​終える」という​決まりの​並びから、​全部の​講座を​受け終えられるかを​答える。​前提の​残り数が​ 0 の​講座から​順に​待ち行列で​取り出す、​トポロジカルソートの​練習です。

海外で定番の問題リスト 4 本のうち 4 本に入っています (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150)

問題

講座が n 個あり、0 から n - 1 の番号が付いています。前提の決まりの並び reqs を受け取ります。reqs の 1 つ [a, b] は、「講座 a を受ける前に、講座 b を終えておく」という意味です。決まりを全部守って、n 個の講座を全部受け終えられるなら真、できないなら偽を返す関数を書いてください。

  • 講座は 1 つずつ受け、受け終えた講座は前提として何度でも使えます
  • n は 1 以上 2000 以下、reqs の長さは 0 以上 5000 以下です
  • 決まりの a と b は違う番号で、同じ決まりは 2 回出てきません

入力と出力の例

例 1

0、1、2 の順に受ければ、決まりを全部守れます。

入力

n = 3
reqs = [[1, 0], [2, 1]]

出力

true

例 2

講座 1、2、3 が、互いに前提として輪になっています。講座 0 は受けられても、輪の 3 つはどれも最初に受けられません。

入力

n = 4
reqs = [[1, 0], [2, 1],
  [3, 2], [1, 3]]

出力

false

例 3

講座 3 は、講座 2 と講座 4 の両方を前提にしています。1 のあと 2 と 4、最後に 3 の順で受けられます。講座 0 には前提が無く、いつでも受けられます。

入力

n = 5
reqs = [[4, 1], [2, 1],
  [3, 4], [3, 2]]

出力

true

面接での聞かれ方

面接では、講座の前提や、作業の依存、部品の組み立て順などの場面で渡されることが多いです。

  • 「依存の決まりがあります。全部を終えられるかを判定してください」
  • 書き終えたあとに「できない理由は何ですか?」「その場合に、輪になっている講座を見つけられますか?」と続けて聞かれます
  • 「受ける順番そのものを返してください」と、続きの問題へ進むこともあります

決まり [a, b] の矢印の向きを、書く前に口で確かめておくことが大切です。b から a へ「b が終わると a へ進める」と矢印を引くと、取り出す順と向きがそろいます。

アルゴリズムのチートシートの「グラフ探索と幅優先探索」に、​この​型の​要点を​表と​コードで​まとめています。

main.py
def can_finish(n, reqs):
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(can_finish(3, [[1, 0], [2, 1]]))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します