
コーディング面接で
アルゴリズムのチートシートに、
日本の企業のコーディングテストの形と対策に、
標準入力から
この頁の目次16 項目
難度と出題の頻度の見方
出題の頻度は、海外でよく使われる定番の問題リスト 4 本 (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150) に何本入っているかで、よく出る・ときどき出る・少なめ の 3 段階に分けています。少なめは、
難度の目安
- 型を
1 つ 知っていれば 解ける 基本の 問い。 LeetCode の Easy ほど - 型を
選び、 端の 場合まで 詰めて 解く 問い。 LeetCode の Medium ほど - 型を
組み合わせるか、 計算量を 一段縮める 工夫が 要る 問い。 Medium の 難しい 物と Hard - いく
つもの 操作を 持つ仕組みを、 データの 持ち方から 設計して作る問い
準備の
最優先の 8 問先にここから
ツーポインタ
並べ替えと
ツーポインタで 和が 0 に なる 3 つ組を 全部出す 整数の
並びから、 足すと 0 に なる 3 つの 数の 組を、 同じ組を 2 回出さずに 全部 返します。 並べ替えて 1 つ目を 固定し、 残り 2 つを ツーポインタで 探し、 重なりを 飛ばす理由まで 言える 練習です。 ソートと
ツーポインタで 和が 目標に なる 4 つの 組を 全部 集める 整数の
並びから、 足すと 目標に なる 4 つの 数の 組を、 重ならないように 全部 返します。 並べ替えてから 外側の 数を 順に 決め、 最後の 2 つを 両端の 指で 探す形に 組み立てる 練習です。 ツーポインタで
並んだ壁の あいだに たまる 雨水の 量を 求める 幅 1 の
壁の 高さの 並びから、 雨が 降った あと 壁の あいだに たまる 水の 量を 求めます。 両端から 2 本の 指を 寄せ、 低い 側の 水の 高さは もう 決まっていると 見抜く、 ツーポインタの 練習です。
- 並べ替えと
ツーポインタで 和が 0 に なる 3 つ組を全部出す整数の並びから、足すと 0 になる 3 つの数の組を、同じ組を 2 回出さずに全部返します。並べ替えて 1 つ目を固定し、残り 2 つをツーポインタで探し、重なりを飛ばす理由まで言える練習です。 - ソートと
ツーポインタで 和が 目標に なる 4 つの 組を 全部集める整数の並びから、足すと目標になる 4 つの数の組を、重ならないように全部返します。並べ替えてから外側の数を順に決め、最後の 2 つを両端の指で探す形に組み立てる練習です。 - ツーポインタで
並んだ壁の あいだに たまる 雨水の 量を求める幅 1 の壁の高さの並びから、雨が降ったあと壁のあいだにたまる水の量を求めます。両端から 2 本の指を寄せ、低い側の水の高さはもう決まっていると見抜く、ツーポインタの練習です。
スライディングウィンドウ
スタック
連結リスト
二分探索
木 (DFS と BFS)
辞書と
再帰で 前順と 中順の 並びから 二分木を 組み直す 二分木を
前順と 中順で たどった 2 つの 並びから、 元の 木を 組み直して 返します。 前順で 根を 決め、 中順で 左右を 分ける 再帰に、 位置を 引く 辞書を 組み合わせて O(n) に する 練習です。 再帰で
二分木の 道の 値の 合計が いちばん 大きくなる 所を探す 二分木の
中で、 節を つないだ道の 値の 合計の うち、 いちばん 大きい 値を 返します。 負の 値の 枝を 切り 捨てながら、 下へ 伸ばせる 片道の 和を 返し、 ついでに 曲がる 道を 比べる 再帰の 練習です。 前順の
走査で 二分木を 文字列に して、 文字列から 同じ木に 組み直す 二分木を
1 本の 文字列に 直す serialize と、 その 文字列から 同じ木を 組み直す deserialize を 書きます。 空の 子にも 印を 付けて 前順で 並べ、 読む ときも 同じ順で 消費する 再帰の 練習です。
- 辞書と
再帰で 前順と 中順の 並びから 二分木を組み直す二分木を前順と中順でたどった 2 つの並びから、元の木を組み直して返します。前順で根を決め、中順で左右を分ける再帰に、位置を引く辞書を組み合わせて O(n) にする練習です。 - 再帰で
二分木の 道の 値の 合計が いちばん 大きくなる所を探す二分木の中で、節をつないだ道の値の合計のうち、いちばん大きい値を返します。負の値の枝を切り捨てながら、下へ伸ばせる片道の和を返し、ついでに曲がる道を比べる再帰の練習です。 - 前順の
走査で 二分木を 文字列に して、 文字列から 同じ木に組み直す二分木を 1 本の文字列に直す serialize と、その文字列から同じ木を組み直す deserialize を書きます。空の子にも印を付けて前順で並べ、読むときも同じ順で消費する再帰の練習です。
二分探索木
トライ木
グラフ
最短経路 (BFS)
区間
バックトラック
動的計画法 (DP)
動的計画法
(DP) と 二分探索で 最長の 増える 部分列を 求める 整数の
並びから、 順を 保ったまま 飛び飛びに 選んで、 どんどん 大きくなる 数の 列を 作る とき、 その 最も 長い 長さを 求める。 O(n²) の DP から 入り、 長さごとの 「最も 小さい 末尾」を 二分探索で 直す O(n log n) に 縮めます。 動的計画法で
2 つの 単語の 編集距離を 求める 1 文字の
挿入、 削除、 置き換えを 何回すれば、 ある 単語を 別の 単語に 変えられるかの 最小を 求めます。 2 次元の 表で 考え、 記憶を 表の 1 行分まで 縮める ところまで 詰める 練習です。 0-1 ナップサックで
荷物を 同じ 重さの 2 組に 分ける 荷物の
重さの 並びを、 重さの 合計が 同じ 2 組に 分けられるかを 調べます。 「半分の 重さちょうどの 選び方が あるか」に 言い換え、 1 次元の 表を 後ろから 埋める 0-1 ナップサックの 練習です。 動的計画法で
2 つの 文字列を 順を 保って 混ぜると 3 つ目に なるか 調べる 2 つの
文字列の 文字を、 それぞれの 順を 変えずに 交互に 混ぜて 3 つ目の 文字列が 作れるかを 確かめます。 2 つの 文字列から 使った 文字数を 表の 縦と 横に 取り、 作れる 所を 埋めていく 練習です。 動的計画法で
低い マスから 順に 埋め、 グリッドの 上り続ける 最長の 道を 求める 高さの
書かれた グリッドを、 上下左右の 隣へ 高さが 上がり続けるように 進むとき、 通れる マスの 数の 最大を 求めます。 低い マスから 順に 「そこで 終わる 道の 長さ」を 決めていく 練習です。 動的計画法で
文字列から 別の 文字列を 拾い出す方法を 数える 文字列 s から、
順番を 変えずに 文字を 拾って 文字列 t を 作る 拾い方が 何通り あるかを 数えます。 t の 前から 何文字までを 作ったかごとの 数を、 s の 文字を 1 つずつ 読みながら 更新する 練習です。 区間の
動的計画法で 最後に 割る 風船を 決め、 得点の 合計を 最大にする 並んだ
風船を 1 つずつ 割り、 割った 風船と 左右の 隣の 数の 積を 得点に する とき、 合計の 最大を 求めます。 区間の 中で 「最後に 割る 風船」を 決めて、 左右を 別々の 小さな 区間に 分ける 練習です。 動的計画法で
ドットと アスタリスクの 入った 型が 文字列全体に 合うか 調べる 「どの
1 文字でも よい」の ドットと 「直前の 1 文字を 0 回以上くり返す」の アスタリスクを 使った 型が、 文字列の 全体に 合うかを 確かめます。 文字列と 型の 前から 何文字ずつが 合うかを 表に して 埋める 練習です。
- 動的計画法 (DP) と
二分 探索で 最長の 増える 部分列を求める整数の並びから、順を保ったまま飛び飛びに選んで、どんどん大きくなる数の列を作るとき、その最も長い長さを求める。O(n²) の DP から入り、長さごとの「最も小さい末尾」を二分探索で直す O(n log n) に縮めます。 - 動的計画法で
2 つの 単語の 編集距離を求める1 文字の挿入、削除、置き換えを何回すれば、ある単語を別の単語に変えられるかの最小を求めます。2 次元の表で考え、記憶を表の 1 行分まで縮めるところまで詰める練習です。 - 0-1 ナップサックで
荷物を 同じ 重さの 2 組に分ける荷物の重さの並びを、重さの合計が同じ 2 組に分けられるかを調べます。「半分の重さちょうどの選び方があるか」に言い換え、1 次元の表を後ろから埋める 0-1 ナップサックの練習です。 - 動的計画法で
2 つの 文字列を 順を 保って 混ぜると 3 つ目に なるか調べる2 つの文字列の文字を、それぞれの順を変えずに交互に混ぜて 3 つ目の文字列が作れるかを確かめます。2 つの文字列から使った文字数を表の縦と横に取り、作れる所を埋めていく練習です。 - 動的計画法で
低い マスから 順に 埋め、 グリッドの 上り続ける 最長の 道を求める高さの書かれたグリッドを、上下左右の隣へ高さが上がり続けるように進むとき、通れるマスの数の最大を求めます。低いマスから順に「そこで終わる道の長さ」を決めていく練習です。 - 動的計画法で
文字列から 別の 文字列を 拾い出す方法を数える文字列 s から、順番を変えずに文字を拾って文字列 t を作る拾い方が何通りあるかを数えます。t の前から何文字までを作ったかごとの数を、s の文字を 1 つずつ読みながら更新する練習です。 - 区間の
動的計画法で 最後に 割る 風船を 決め、 得点の 合計を 最大にする並んだ風船を 1 つずつ割り、割った風船と左右の隣の数の積を得点にするとき、合計の最大を求めます。区間の中で「最後に割る風船」を決めて、左右を別々の小さな区間に分ける練習です。 - 動的計画法で
ドットと アスタリスクの 入った 型が 文字列全体に 合うか調べる「どの 1 文字でもよい」のドットと「直前の 1 文字を 0 回以上くり返す」のアスタリスクを使った型が、文字列の全体に合うかを確かめます。文字列と型の前から何文字ずつが合うかを表にして埋める練習です。
設計
海外の
そろった問題 149 / 150 問。準備中の
配列とハッシュ9 / 9 問
ツーポインタ5 / 5 問
スライディングウィンドウ6 / 6 問
スタック7 / 7 問
二分探索7 / 7 問
連結リスト11 / 11 問
- 35連結リストの
つなぎ先を 付け替えて 逆順にする - 36ダミーの
節で 2 本の 並んだ 連結リストを 1 本にまとめる - 37半分に
分けて 後ろを 逆にし、 連結リストを 前と 後ろから 互い 違いに並べ直す - 38間を
あけた 2 本の 指で 連結リストの 後ろから n 番目の節を外す - 39元の
節と 写しの 対応表で random つきの 連結リストを 丸ごと写す - 40繰り
上がりを 持ちながら、 1 の 位から 並んだ 2 本の 連結リストの数を足す - 41速い指と
遅い指で 連結リストの 輪を見つける - 42速い指と
遅い指で 並びの 中の 重なった数を探す - 43辞書と
双方 向リストで LRU キャッシュを設計する - 442 本ずつまとめて
k 本の 並んだ 連結リストを 1 本にする - 45つなぎ先の
付け替えで 連結リストを k 個ずつ逆順にする
木15 / 15 問
- 46再帰で
二分木を 左右反転する - 47深さ優先探索 (DFS) で
二分木の 深さを求める - 48再帰で
二分木の いちばん長い 道の 長さを求める - 49再帰で
二分木の 高さが 釣り合っているか確かめる - 50再帰で
2 本の 二分木が 同じか確かめる - 51再帰で
二分木の 中に 別の 木と 同じ 部分木が あるか確かめる - 52二分探索木の
大小で 2 つの 節の 共通の 祖先を探す - 53幅優先探索 (BFS) と
キューで 二分木を 段ごとに読む - 54幅優先探索 (BFS) で
二分木を 右から 見た ときに 見える 節を並べる - 55深さ優先探索で
根からの 道で いちばん 大きい値を 持ち回り、 二分木の よい 節を数える - 56再帰で
二分探索木の 決まりを確かめる - 57スタックの
中順の 走査で 二分探索木の k 番目に 小さい値を探す - 58辞書と
再帰で 前順と 中順の 並びから 二分木を組み直す - 59再帰で
二分木の 道の 値の 合計が いちばん 大きくなる所を探す - 60前順の
走査で 二分木を 文字列に して、 文字列から 同じ木に組み直す
トライ木3 / 3 問
ヒープ7 / 7 問
バックトラック9 / 9 問
グラフ12 / 13 問
- 80幅優先探索 (BFS) で
グリッドの 島を数える - 81幅優先探索 (BFS) と
辞書で つながりの グラフを写し取る - 82深さ優先探索 (DFS) で
グリッドの いちばん 大きい島の 広さを求める - 83幅優先探索 (BFS) で
東と 西の 両方の 海へ 流れる 場所を探す - 84盤の
端から たどって 囲まれた 空き地だけを埋める - 85幅優先探索 (BFS) で
知らせが 全員に 届くまでの 分を数える - 86幅優先探索 (BFS) で
全部の 部屋から いちばん近い 出口までの 歩数を求める - 87トポロジカルソートで
全部の 講座を 受けられるか調べる - 88トポロジカルソートと
ヒープで 講座を 受ける 順を決める - 89素集合 (Union-Find) で
木に 1 本だけ足された 余分な 道を見つける - 90つながった組の数準備中
- 91幅優先探索 (BFS) の
色塗りで、 つながった 2 人を 別の 組に 分けられるか調べる - 92幅優先探索 (BFS) で
言葉の 梯子の いちばん短い 長さを求める
グラフの応用6 / 6 問
1 次元の動的計画法12 / 12 問
- 99動的計画法 (DP) で
階段の 上り方を数える - 100動的計画法で
通行料つきの 階段を いちばん安く上る - 101動的計画法で
隣り合わない 要素の 合計を 最大にする - 102動的計画法で
輪に なった 並びから 隣り合わない 合計を 最大にする - 103まん中から
広げて 最も 長い 回文の 部分文字列を探す - 104まん中から
広げて 回文に なっている 部分文字列を 全部数える - 105動的計画法で
数字だけの 暗号を 文字に 戻す読み方を数える - 106動的計画法 (DP) で
おつりの 硬貨の 枚数を 最も 少なくする - 107動的計画法で
最大と 最小の 積を 持ち 歩き、 積が 最大の 続いた 区間を求める - 108動的計画法で
文字列を 辞書の 単語に 区切れるか調べる - 109動的計画法 (DP) と
二分 探索で 最長の 増える 部分列を求める - 1100-1 ナップサックで
荷物を 同じ 重さの 2 組に分ける
2 次元の動的計画法11 / 11 問
- 111動的計画法で
碁盤の 目の 左上から 右下への 道順を数える - 112動的計画法で
2 つの 文字列に 共通する 最長の 部分列を求める - 113動的計画法で
売った 次の 日は 買えない 決まりの 売り 買いの 利益を 最大にする - 114動的計画法で
硬貨の 組み合わせが 何通り あるかを数える - 115部分和の
数え上げで 符号の 付け方を数える - 116動的計画法で
2 つの 文字列を 順を 保って 混ぜると 3 つ目に なるか調べる - 117動的計画法で
低い マスから 順に 埋め、 グリッドの 上り続ける 最長の 道を求める - 118動的計画法で
文字列から 別の 文字列を 拾い出す方法を数える - 119動的計画法で
2 つの 単語の 編集距離を求める - 120区間の
動的計画法で 最後に 割る 風船を 決め、 得点の 合計を 最大にする - 121動的計画法で
ドットと アスタリスクの 入った 型が 文字列全体に 合うか調べる
貪欲法8 / 8 問
区間6 / 6 問
数学と幾何8 / 8 問
ビット演算7 / 7 問
そのほかの問題22 問
- ランレングス圧縮で
続く 同じ 文字を縮める - 割り算と
余りで 整数が 回文かを確かめる - 文字列の
単語を 逆順に 並べ替える - ハッシュで
最初の 重複しない 文字を探す - ツーポインタで
0 を 配列の 末尾へ移す - ソートと
ツーポインタで 目標に いちばん近い 3 つの 和を求める - 3 本の
指で 0 と 1 と 2 の 並びを 1 回で 並べ替える - ソートと
ツーポインタで 和が 目標に なる 4 つの 組を 全部集める - スライディングウィンドウで
続いた 1 の 最長を数える - スライディングウィンドウで
幅 k の 平均が 最大の所を探す - 再帰で
入れ子の 配列を 平らにする - 二分探索で
挿入位置を求める - 二分探索で
同じ 値が 続く 範囲の 両端を探す - 二分探索で
上って 下る 並びの 頂上を探す - 深さ優先探索で
二分木の 根から 葉までの 合計を調べる - 再帰で
二分木の 2 つの 節に いちばん近い 共通の 祖先を探す - 再帰で
並びから 高さの そろった 二分探索木を作る - 繰り返しで
二分探索木に 新しい 値を 葉として足す - 再帰で
二分探索木から 値を 消して 木を つなぎ直す - 幅優先探索 (BFS) で
グリッドの 最短の 道を数える - 素集合 (Union-Find) で
つながった 町の まとまりを数える - 辞書と
並びを 組み合わせて O(1) で 出し入れと 無作為な 取り出しが できる 集合を作る
解いた
言葉で