1. [cat,car,dog] prefix=ca -> true
  2. [cat,car,dog] prefix=do -> true
  3. [cat,car,dog] prefix=ba -> false
  4. exact match works as prefix
  5. longer than any word -> false
  6. empty prefix -> true
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
trie の単純検索 (prefix マッチ)

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

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

trie の単純検索 (prefix マッチ)

10 万語を頭から突き合わせると間に合わない

検索ボックスに 1 文字入るたびに、候補の一覧から「その文字列で始まる単語があるか」を出したいとします。素直に書けば、候補を全部順に見ることになります。

JavaScript

words.some(word => word.startsWith(input));

候補が 3 語なら何の問題もありません。10 万語あって、1 文字打つたびに全部を見るとなると、指の速さに追いつかなくなります。しかも無駄が多い。ほとんどの単語は 1 文字目で外れるのに、毎回 1 語ずつ取り出しては最初の文字から比べ直しています。

同じ書き出しを 1 本の枝にまとめる

sun sum sea の 3 語で考えます。sun と sum は su まで同じで、sea とも s を共有しています。この重なりを、あらかじめ 1 本の枝として持っておくのが trie です。

diagram (will load when visible)

1 つの節が 1 文字を持ち、その先に「次に来られる文字」だけがぶら下がっています。入れ物は特別なものでなくてよく、次の文字をキーにした辞書を入れ子にすれば、この形がそのまま表せます。

JavaScript

{ s: { u: { n: {}, m: {} }, e: { a: {} } } }

1 文字ずつ枝を降りる

su で始まる単語があるかを知りたいとき、やることは 2 手だけです。根の辞書に s のキーがあるか見て、あればその中へ移る。次に u のキーがあるか見て、あればその中へ移る。最後まで移れたなら、そこから先にぶら下がっているものはすべて su で始まる単語なので、答えは「ある」です。

途中でキーが無ければ、その場で答えが決まります。sun しか入っていないところに sunny を聞かれたら、n の先に次の n の枝が無いので、そこで打ち切ります。候補が 3 語でも 10 万語でも、見る回数は入力した文字数と同じです。増えるのは作るときの手間だけで、1 度作った枝は何度でも使い回せます。

検索窓の入力補完のほかに、郵便番号や電話番号の前方一致、IP アドレスの経路表のように、「先頭から一致する範囲を絞りたい」場面では同じ形が出てきます。共通の書き出しを 1 本にまとめてあるので、置き場所も単語をそのまま並べるより小さく済みます。

なお、入力が空文字列のときは 1 手も降りません。何も確かめないまま最後まで移れたことになるので、答えは「ある」になります。

今回は「始まるか」だけを答えるので、単語の終わりを示す印は要りません。sun と sunny の両方を入れて「sun という単語そのものがあるか」まで区別したくなったとき、初めて終わりの印が必要になります。

解説

覚え方 ... 突き合わせるのは単語ではなく文字。降りられなくなった時点で答えが出る。

要件

  1. words の各文字を trie (辞書のネストなど) に挿入する処理を内部に書くこと
  2. プレフィックスをルートからたどれれば true、途中で枝がなくなれば false を返す
  3. 空文字列のプレフィックスは常に true を返す

入出力例

hasPrefix(["cat","car","dog"], "ca") → true hasPrefix(["cat","car","dog"], "do") → true hasPrefix(["cat","car","dog"], "ba") → false hasPrefix(["cat","car"], "cat") → true hasPrefix(["cat"], "cats") → false hasPrefix(["cat"], "") → true

ヒント

trie はネストした辞書 {} で表現するのが簡単。各文字をキー、子辞書を値にする

構築フェーズと検索フェーズで node を 2 回 trie にリセットする (構築後にもう一度 root から始める)

プレフィックスの長さ分だけたどれれば true。最後まで届けば成功

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

関連レッスン

  • Union-Find (連結成分数)

    Union-Find (Disjoint Set Union) を使い、辺の集合からグラフの連結成分の数を求める関数を実装する。森のような構造でグループを管理する手法を学ぶ。

  • 最終総まとめクイズ

    cs-system-design コース全体の総まとめクイズ。連結リスト、二分木、BST、ハッシュ、グラフ、動的計画法、関数型の知識を確認する。

  • カリー化

    2 引数の関数を 1 引数の関数のチェーン `f(a)(b)` に変換するカリー化を内部で組み立てて適用する。`add(a, b)` をカリー化して `add(a)(b)` の形で呼び出した結果を返す関数を実装する。

  • 関数合成

    `compose(f, g)(x) = f(g(x))` の関数合成を関数の中で組み立てて適用する。`addOne` と `double` を合成して値に適用した結果を返す関数を実装する。

main.py
学習モード
エディタを読み込んでいます

メモ

trie の単純検索 (prefix マッチ)

⌘S で保存