1. 鎖 0->1->2->3
  2. 辺なし
  3. 扇型 (1->3, 2->3)
  4. 複雑 DAG
  5. 1 ノード
  6. ダイヤモンド
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
トポロジカルソート

コンピューターサイエンス上級:アルゴリズムとデータ構造

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な CS の知識を持ち、アルゴリズム力を伸ばしたい学習者や、外資・大手の技術面接対策をしたい方を対象としています。約 13 時間 (1 日 30 分 × 26 日) で 50 レッスンを修了でき、修了後はコーディング面接の実装問題を構造的に解けるようになります。

1
連結リスト
01. リンクリスト構築と長さの計算5分
02. リンクリストの反転5分
03. リンクリストのサイクル検出5分
04. ソート済みリンクリストの merge5分
05. リンクリストの中央ノード取得5分
06. ソート済みリストの重複削除5分
07. 第1章まとめクイズ5分
2
二分木
01. 二分木の in-order 走査5分
02. 二分木の pre-order 走査5分
03. 二分木の post-order 走査5分
04. 二分木の幅優先走査 (BFS)5分
05. 二分木の高さ5分
06. 二分木の平衡判定5分
07. 第2章まとめクイズ — 二分木5分
3
探索木 (BST)
01. BST に値を挿入する5分
02. BST から値を検索する5分
03. BST の最小値と最大値5分
04. BST 妥当性チェック5分
05. BST で k 番目に小さい値5分
06. BST から値を削除する5分
07. 第 3 章 まとめクイズ5分
4
ハッシュとセット
01. hashmap で頻度集計5分
02. キーでグループ化5分
03. two sum (hash で O(n))5分
04. 部分配列の和 = k の個数5分
05. 最長連続部分列5分
06. 集合の積 (intersection)5分
07. 第4章まとめクイズ5分
5
グラフ
01. グラフ BFS で連結成分サイズを求める5分
02. グラフ DFS で連結成分の数を数える5分
03. グラフのパス存在判定5分
04. BFS で最短経路の長さを求める5分
05. トポロジカルソート5分
06. 2 部グラフ判定5分
07. ダイクストラ法 — 重み付きグラフの最短経路15分
08. 第5章まとめクイズ — グラフ5分
6
動的計画法 (上級)
01. 編集距離 (レーベンシュタイン距離)5分
02. 最長増加部分列(LIS)の解法 ── AOJ 2430 対応の動的計画法5分
03. 最大部分配列和 (Kadane)5分
04. 隣り合わない最大値 (House Robber)5分
05. グリッド経路数 (Unique Paths)5分
06. 単語分割可能か (Word Break)5分
07. 第6章まとめクイズ — 動的計画法 (上級)5分
7
総合データ構造と関数型
01. map と filter を組み合わせる5分
02. reduce で積を計算5分
03. 関数合成5分
04. カリー化5分
05. trie の単純検索 (prefix マッチ)5分
06. Union-Find (連結成分数)5分
07. 最終総まとめクイズ5分

トポロジカルソート

どれから手をつければいいのか分からない

ビルドの手順、履修の順番、料理の段取り。どれも「これを終えてからでないと、あれに進めない」という条件の集まりです。条件が 2 つ 3 つならすぐ並べられますが、50 個になると人の頭では並べられません。

条件は「A が終わってから B」という向きのある矢印で書けます。矢印をすべて満たす一列の並びを作るのがトポロジカルソートです。

ここまでと違い、扱うのは 向きのあるつながり です。無向グラフのくせで両方向に辺を張ると「先」と「後」の区別が消えて、答えが出なくなります。一覧の [u, v] は u から v への一方通行として登録します。

待っている数を数える

考え方は現場の段取りと同じです。まず、それぞれの作業が「いくつの作業を待っているか」を数えます。待ち数が 0 の作業は、今すぐ始められます。

Python

prereq = { "線形代数": [], "微積分": [], "機械学習": ["線形代数", "微積分"], "深層学習": ["機械学習"], } waiting = {name: len(reqs) for name, reqs in prereq.items()} ready = [name for name, count in waiting.items() if count == 0] print(ready) # ['線形代数', '微積分']

待ち数 0 の作業を 1 つ終えたら、その作業を待っていた相手の待ち数を 1 ずつ減らします。減らした結果 0 になった相手は、そのとき初めて手が空きます。

Python

done = "線形代数" for name, reqs in prereq.items(): if done in reqs: waiting[name] -= 1 # 0 になったら着手できる

これを、手の空いた作業が無くなるまで繰り返します。取り出した順番が、そのまま答えの並びです。減らすのは 取り出したあと です。取り出す前に減らすと、まだ終わっていない作業の分まで解放してしまいます。

課題では、待ち数 0 の作業が同時に複数あるとき 番号の小さいほうを先に 取り出す決まりにしています。ふつうのキューは入れた順に出るので、小さい順に取り出せる入れ物 (Python なら heapq) を使うか、取り出すたびに最小を選びます。

一周して戻る条件は、並べられない

「A の前に B」「B の前に A」と書かれたら、どう並べても矛盾します。待ち数を減らす方式なら、この状況は自然に見つかります。まだ並べ終わっていないのに、待ち数 0 の作業が 1 つも残っていない状態になるからです。

ビルドツールが circular dependency と怒るのは、まさにこの瞬間です。並べ終えた個数が全体の個数に届いているかを見れば、順番を出すのと同時に循環も検出できます。

やってみよう

  • 上の履修表を手で並べる。線形代数と微積分が先、そのあと機械学習、最後に深層学習
  • 矢印が 1 本もないとき、答えは全部の点が番号順に並んだものになる
  • 鎖状の [[0,1],[1,2],[2,3]] は並び方が 1 通りしかない。[[0,1],[0,2],[1,3],[2,3]] は複数あるので、取り出し方の決まりが効いてくる

要件

  1. Kahn のアルゴリズム (入次数を使う BFS) で実装すること
  2. 同点 (入次数 0 が複数) のときは ID が小さいノードを先に取り出すこと
  3. 有向エッジは片方向のみ追加すること

入出力例

topoSort(4, [[0,1],[1,2],[2,3]]) → [0,1,2,3] topoSort(3, []) → [0,1,2] topoSort(4, [[0,1],[0,2],[1,3],[2,3]]) → [0,1,2,3] topoSort(5, [[0,1],[0,2],[1,3],[2,3],[3,4]]) → [0,1,2,3,4] topoSort(1, []) → [0] topoSort(6, [[0,1],[0,2],[1,3],[2,3],[3,4],[3,5]]) → [0,1,2,3,4,5]

ヒント

入次数 0 のノードはどこにも依存していない (= 最初に処理できる)

u を取り出したら、u の出力辺をたどって v の入次数を -1 する。0 になったらキューに入れる

ID 昇順を保証するなら通常の deque ではなく最小ヒープ (heapq / PriorityQueue) を使うのが定石

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 2 部グラフ判定

    無向グラフが 2 部グラフかどうかを BFS の彩色で判定する関数を実装する。

  • ダイクストラ法 — 重み付きグラフの最短経路

    重み付きグラフでの最短経路問題を解くダイクストラ法を、概念・図・擬似コード・Python 実装・計算量・よくある誤解まで一気通貫で学ぶ。

  • 第5章まとめクイズ — グラフ

    BFS / DFS / 最短経路 / トポロジカルソート / 2 部グラフ判定について理解度を確認する 4 択クイズ。

  • 編集距離 (レーベンシュタイン距離)

    2 つの文字列を一致させるために必要な最小編集回数を、二次元 DP で求める古典問題に挑戦します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • グラフノード(頂点)とエッジ(辺)で構成されるデータ構造。
  • キュー先入れ先出し(FIFO)のデータ構造
  • 機械学習データからパターンを学習してルールを自動で獲得する手法。
  • アルゴリズム問題を効率よく解く手順
main.py
学習モード
エディタを読み込んでいます

メモ

トポロジカルソート

⌘S で保存