1. 2 つの成分 + 孤立ノード -> 3
  2. 完全孤立 -> n=4
  3. 鎖状全連結 -> 1
  4. 三角形 + 鎖 -> 2
  5. 1 ノード -> 1
  6. 星型 -> 1
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
グラフ DFS で連結成分の数を数える

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

探索、ソート、木、グラフ、動的計画法、貪欲法など、競技プログラミングや技術面接で問われる高度なアルゴリズムとデータ構造を学べるコースです。基本的な 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分

グラフ DFS で連結成分の数を数える

塊がいくつあるかは、目では数えられない

前のレッスンでは起点を 1 つ決めて、そこから届く範囲の大きさを数えました。今度は範囲ではなく 塊の数 を知りたい。つながりの一覧だけを渡されて、「このネットワークはいくつのグループに分かれていますか」と聞かれる状況です。

点が 6 つなら絵を描けば数えられます。10,000 点になると描けません。しかも、どの点が同じ塊に属するのかは、一覧を眺めても分かりません。

数え方は 1 つです。まだ訪れていない点を見つけたら、そこを新しい塊の入口とみなして、そこから届く範囲を全部訪問済みにする。この「新しい入口を見つけた回数」が、そのまま塊の数になります。

行けるところまで行って、戻る

範囲を塗りつぶす役は、深さ優先探索 (DFS) が向いています。1 本の道を行けるところまで進み、行き止まりで 1 歩戻って別の道へ移る。迷路で片手を壁につけて歩くときの動きです。塊の中を余さず塗るのが目的なので、近い順に広げる必要はありません。

この動きは再帰と相性がよく、フォルダの中を潜っていく処理と同じ形になります。

Python

def count_files(folder): total = 0 for entry in folder: if isinstance(entry, list): total += count_files(entry) # 中へ潜る else: total += 1 return total

潜れるだけ潜って、底に着いたら戻ってくる。DFS もこれと同じで、次の隣へ移る前に、今の隣の先を全部片づけます。

再帰を使わずスタックでも書けます。行き先を積んでおき、最後に積んだもの から取り出すと、同じ動きになります。

Python

org = { "部長": ["課長A", "課長B"], "課長A": ["山田", "佐藤"], "課長B": ["鈴木"], "山田": [], "佐藤": [], "鈴木": [], } stack = ["部長"] while stack: person = stack.pop() # 最後に積んだものが出る print(person) stack.extend(org[person])

出力は 部長、課長B、鈴木、課長A、佐藤、山田 の順です。課長B の下を先に全部見てから課長A へ戻っているのが、深く潜る動きです。前のレッスンのキューを使うと、課長A と課長B を先に並べてから下へ降ります。取り出す側が先頭か末尾か、違いはそれだけです。

上の例は組織図なので輪がなく、訪問済みの確認をしていません。グラフでは輪をたどって戻ってくるので、積む前に訪問済みかどうかを見る 1 行が必要です。

数えるのは外側

count を増やす場所を間違えると、答えがまるで変わります。塗りつぶしの中で増やすと「訪問した点の数」になってしまい、結果は必ず点の総数になります。増やしてよいのは、外側のループで まだ訪問していない点を見つけたとき だけです。

再帰で書く場合、Python の再帰の深さは既定で 1,000 前後です。点が鎖のように長くつながっていると途中で止まるので、sys.setrecursionlimit を上げるか、スタック版に切り替えます。

やってみよう

  • n=6, edges=[[0,1],[1,2],[3,4]] を紙に描く。5 番はどこにもつながっていないので、それ自体が 1 つの塊
  • 辺が 1 本もないとき、答えは点の数と同じになる
  • 全部が 1 本の鎖でつながっているとき、答えは 1 になる

要件

  1. DFS (再帰 or スタックを使った反復) で実装すること
  2. 訪問済み配列を使って未訪問の起点を見つけたときだけカウントすること
  3. 無向エッジは両方向に隣接リストへ追加すること

入出力例

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

ヒント

外側のループで未訪問ノードを起点に DFS を始める。DFS を呼んだ回数が連結成分数

再帰深さが心配ならスタック版で書く方が安全

visited は配列 (bool) で十分。set を使ってもよい

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

関連レッスン

  • グラフのパス存在判定

    始点と終点が与えられたとき、その間にパスが存在するかを真偽値で返す関数を実装する。

  • BFS で最短経路の長さを求める

    重みなし無向グラフで、BFS を使って始点から終点までの最短経路 (辺数) を求める関数を実装する。

  • トポロジカルソート

    有向非巡回グラフ (DAG) のノードを、すべての辺 u->v で u が v より前に来るように並べた配列を返す。

  • 2 部グラフ判定

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

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

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

  • ループ繰り返し処理。矢印で戻すか専用記号で示す
  • 再帰関数が自分自身を呼び出す処理パターン
  • 処理計算や代入を表す長方形
  • スタック後入れ先出し(LIFO)のデータ構造
  • キュー先入れ先出し(FIFO)のデータ構造
  • グラフノード(頂点)とエッジ(辺)で構成されるデータ構造。
  • 反復色やフォントを繰り返して秩序を生む
  • 配列サイズ固定の同型データの集まり
main.py
学習モード
エディタを読み込んでいます

メモ

グラフ DFS で連結成分の数を数える

⌘S で保存