1. leetcode + [leet, code] -> true
  2. applepenapple + [apple, pen] -> true
  3. catsandog + [cats, dog, sand, and, cat] -> false
  4. aaaaaaa + [aaaa, aaa] -> true
  5. a + [b] -> false
  6. ab + [a, b] -> true
コース一覧
コンピューターサイエンス上級:アルゴリズムとデータ構造
単語分割可能か (Word Break)

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

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

単語分割可能か (Word Break)

左から欲張って切ると、行き止まる

catsandog という文字列と、cats、cat、sand、and、dog という辞書が渡されます。辞書の単語だけをつなげて、この文字列を作れるでしょうか。

左から順に、辞書にある一番長い単語で切っていきます。cats が取れました。残りは andog。and が取れました。残りは og で、辞書にありません。行き止まりです。

では cat で切っていたら。残りは sandog で、sand が取れて、残りはやはり og。こちらも行き止まりです。この文字列は作れません。

大事なのは、1 回目の切り方を変えると 2 回目以降の選択肢が丸ごと変わるという点です。辞書に単語があるかどうかは一瞬で調べられます。難しいのは どこで区切るか の分かれ道のほうです。

分かれ道は、印に置き換える

分かれ道を素直にたどると、切るたびに枝分かれして指数的に増えます。しかも別々の枝の先で「残りの og から作れるか」という同じ問いを何度も解き直します。編集距離のときと同じ無駄です。

そこで、枝をたどるのをやめて、左から順に印を立てていきます。印の意味は「先頭からここまでは、辞書の単語だけで作れる」です。

ある位置に印が立つのは、その手前のどこかに印が立っていて、そこから今の位置までの文字列が辞書にあるとき です。手前の印は 1 つ見つかれば十分なので、見つけた時点で次の位置へ進めます。

今の位置からどこまで進めるかを見るのは、この形です。

Python

words = {"cats", "cat", "sand", "and", "dog"} s = "catsandog" i = 0 for j in range(i + 1, len(s) + 1): if s[i:j] in words: print(i, "から", j, "まで", s[i:j])

cat と cats の 2 つが出てきます。これが分かれ道です。印を立てる方式なら、どちらの行き先にも印を立てておけばよく、その先はどちらの道からたどっても 1 度しか調べません。枝の数ではなく、文字の位置の数だけ働けば済みます。

辞書は必ず集合 (set や Set) に入れ替えてから使ってください。配列のまま in や includes で調べると、位置を 1 つ試すたびに単語の数だけなぞることになり、全体の速さが一段落ちます。

出発点の印を忘れない

一番左、まだ 1 文字も見ていない位置にも印が要ります。「空の文字列は、単語を 0 個つなげて作れている」とみなすためです。ここに印が立っていないと、手前の印が 1 つも見つからず、どこにも印が立たないまま必ず偽になります。

最後に見るのは、文字列の長さと同じ位置の印です。印の入れ物は文字数より 1 つ長くなるので、うっかり 1 つ手前を見ると、最後の 1 文字を無視した答えになります。

やってみよう

  • leetcode と ["leet", "code"] で真になることを確かめる
  • applepenapple と ["apple", "pen"] は真。同じ単語を何度使ってもよい
  • aaaaaaa と ["aaaa", "aaa"] を手で追う。どこに印が立つか、左から順に書き出してみる

要件

  1. 戻り値は分割可能か否か (boolean)
  2. 辞書を set / HashSet / map に変換してから判定すること (in 判定 O(1))
  3. dp[i] = s の最初 i 文字が分割可能か、として DP で求めること

入出力例

wordBreak("leetcode", ["leet","code"]) → true wordBreak("applepenapple", ["apple","pen"]) → true wordBreak("catsandog", ["cats","dog","sand","and","cat"]) → false wordBreak("aaaaaaa", ["aaaa","aaa"]) → true wordBreak("a", ["b"]) → false wordBreak("ab", ["a","b"]) → true

ヒント

dp[0] = True を初期値とし、dp[i] = ∃ j < i, dp[j] && s[j:i] ∈ wordSet で更新する

wordDict はリストのまま検索すると遅い。set 化して O(1) lookup にする

1 つでも分割が見つかれば break して次の i に進んでよい

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

関連レッスン

  • 第6章まとめクイズ — 動的計画法 (上級)

    編集距離、LIS、Kadane、House Robber、グリッド経路数、Word Break の理解度を確認する 4 択クイズです。

  • map と filter を組み合わせる

    配列に対して `map` と `filter` を組み合わせ、偶数だけを 2 倍した結果を返す関数を実装する。関数型プログラミングの基礎を学ぶ。

  • グリッド経路数 (Unique Paths)

    右と下にのみ進めるグリッドの上で、左上から右下に至る経路の総数を二次元 DP で数えます。

  • 隣り合わない最大値 (House Robber)

    隣り合う要素を同時に選べないという制約の下、配列から取り出せる最大合計を DP で求めます。

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

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

  • 配列サイズ固定の同型データの集まり
  • 戻り値呼び出し元への返答を表す点線矢印
  • HashSetハッシュ表ベースの Set 実装
main.py
学習モード
エディタを読み込んでいます

メモ

単語分割可能か (Word Break)

⌘S で保存