
コーディング面接で
アルゴリズムのチートシートに、
日本の企業のコーディングテストの形と対策に、
標準入力から
この頁の目次16 項目
難度と出題の頻度の見方
出題の頻度は、海外でよく使われる定番の問題リスト 4 本 (Blind 75、NeetCode 150、Grind 75、LeetCode Top Interview 150) に何本入っているかで、よく出る・ときどき出る・少なめ の 3 段階に分けています。少なめは、
難度の目安
- 型を
1 つ 知っていれば 解ける 基本の 問い。 LeetCode の Easy ほど - 型を
選び、 端の 場合まで 詰めて 解く 問い。 LeetCode の Medium ほど - 型を
組み合わせるか、 計算量を 一段縮める 工夫が 要る 問い。 Medium の 難しい 物と Hard - いく
つもの 操作を 持つ仕組みを、 データの 持ち方から 設計して作る問い
準備の
最優先の 8 問先にここから
文字列
配列とハッシュ
Two Sum を
ハッシュマップで解く 整数の
並びから、 足すと 目標の 数に なる 2 つを 探し、 その 位置を 返す。 見た数を 辞書に 覚えて おくと、 並びを 1 回なめるだけで 見つかります。 アナグラムか
どうかを ハッシュで 判定する 2 つの
文字列が、 文字を 並べ替えるだけで 同じに できるかを 調べる。 並べ替えて 比べる 書き方と、 文字の 数を 数える 書き方を 比べる 練習です。 ハッシュで
最初の 重複しない 文字を探す 文字列の
中で 1 回しか 出ない 文字の うち、 いちばん前に ある物の 位置を 返す。 先に 全部を 数え、 もう 1 回読んで 探す、 2 回なめる 考え方の 練習です。 集合で
同じ値が 2 回出てくるかを 確かめる 整数の
並びの 中に、 同じ 値が 2 回以上 出てくるかを 判定します。 見た値を 集合に 覚え、 出てきた 値が もう 集合に あるかを 一定の 手間で 調べる 練習です。
- Two Sum を
ハッシュマップで解く整数の並びから、足すと目標の数になる 2 つを探し、その位置を返す。見た数を辞書に覚えておくと、並びを 1 回なめるだけで見つかります。 - アナグラムか
どうかを ハッシュで判定する2 つの文字列が、文字を並べ替えるだけで同じにできるかを調べる。並べ替えて比べる書き方と、文字の数を数える書き方を比べる練習です。 - ハッシュで
最初の 重複しない 文字を探す文字列の中で 1 回しか出ない文字のうち、いちばん前にある物の位置を返す。先に全部を数え、もう 1 回読んで探す、2 回なめる考え方の練習です。 - 集合で
同じ 値が 2 回出てくるかを確かめる整数の並びの中に、同じ値が 2 回以上出てくるかを判定します。見た値を集合に覚え、出てきた値がもう集合にあるかを一定の手間で調べる練習です。
数学と行列
ビット操作
全部を
XOR で まとめ、 1 回だけ出てくる 値を 見つける 1 つを
除いてどの 値も ちょうど 2 回ずつ 出てくる 並びから、 1 回だけ出てくる 値を 返します。 同じ 値どうしの XOR は 0 に なるので、 全部を XOR で まとめれば対の 値が 消えて 1 つだけ 残る 練習です。 いちばん下の
1 を 消していき、 2 進の 1 の 数を 数える 0 以上の
整数を 2 進で 書いた ときの 1 の 数を 返します。 n & (n - 1) で いちばん下の 1 の ビットを 1 つずつ消せば、 1 の 数の 回数だけ回して 数えられる 練習です。 半分の
数の 答えを 使い回し、 0 から n までの 1 の ビットの 数を 並べる 0 から
n までの 各数に ついて、 2 進で 書いた ときの 1 の 数を 並べて 返します。 i を 1 ビット 右へずらした 数の 答えは もう 出ているので、 それに いちばん下の ビットを 足すだけで 次々に 埋まる 練習です。 下の
ビットから 取り出して 上へ 積み、 32 ビットを 逆順にする 0 以上の
整数を 32 ビットの 並びと して 見て、 ビットの 並びを 左右逆に した 数を 返します。 下の ビットを 1 つずつ 取り出し、 答えを 左へずらしながら 積んでいく 練習です。 番号と
値を 全部 XOR で まとめ、 0 から n の 中で 抜けた 数を 見つける 0 から
n までの n + 1 個の 数の うち、 1 つだけが 抜けた 長さ n の 並びから、 抜けた 数を 返します。 0 から n の 番号と 並びの 値を 全部 XOR で まとめれば、 そろった 数は 打ち消し合って 抜けた 数だけが 残る 練習です。
- 全部を
XOR で まとめ、 1 回だけ 出てくる 値を見つける1 つを除いてどの値もちょうど 2 回ずつ出てくる並びから、1 回だけ出てくる値を返します。同じ値どうしの XOR は 0 になるので、全部を XOR でまとめれば対の値が消えて 1 つだけ残る練習です。 - いちばん下の
1 を 消していき、 2 進の 1 の 数を数える0 以上の整数を 2 進で書いたときの 1 の数を返します。n & (n - 1) でいちばん下の 1 のビットを 1 つずつ消せば、1 の数の回数だけ回して数えられる練習です。 - 半分の
数の 答えを 使い回し、 0 から n までの 1 の ビットの 数を並べる0 から n までの各数について、2 進で書いたときの 1 の数を並べて返します。i を 1 ビット右へずらした数の答えはもう出ているので、それにいちばん下のビットを足すだけで次々に埋まる練習です。 - 下の
ビットから 取り出して 上へ 積み、 32 ビットを 逆順にする0 以上の整数を 32 ビットの並びとして見て、ビットの並びを左右逆にした数を返します。下のビットを 1 つずつ取り出し、答えを左へずらしながら積んでいく練習です。 - 番号と
値を 全部 XOR で まとめ、 0 から n の 中で 抜けた 数を見つける0 から n までの n + 1 個の数のうち、1 つだけが抜けた長さ n の並びから、抜けた数を返します。0 から n の番号と並びの値を全部 XOR でまとめれば、そろった数は打ち消し合って抜けた数だけが残る練習です。
ツーポインタ
スライディングウィンドウ
窓の
左端に 最安値を 置いて 1 回の 売り 買いの 利益を 最大にする 日ごとの
値段の 並びから、 1 回だけ 買って、 それより 後の 日に 1 回だけ売る ときの、 いちばん 大きい 利益を 返します。 窓の 左端を それまでの 最安の 日に 置き、 右端を 1 日ずつ 進める 練習です。 スライディングウィンドウで
続いた 1 の 最長を 数える 0 と
1 だけの 並びから、 1 が いちばん長く 続いた 所の 長さを 返します。 並びを 1 回なめながら、 いま続いている 長さと 最長を 覚えて おく 練習です。 スライディングウィンドウで
幅 k の 平均が 最大の 所を探す 整数の
並びで、 続いた k 個の 平均が いちばん 大きくなる 所を 探し、 その k 個の 合計を 返します。 窓を 1 つずらすたびに、 入る 数を 足して 出る 数を 引く 練習です。
- 窓の
左端に 最安値を 置いて 1 回の 売り 買いの 利益を 最大にする日ごとの値段の並びから、1 回だけ買って、それより後の日に 1 回だけ売るときの、いちばん大きい利益を返します。窓の左端をそれまでの最安の日に置き、右端を 1 日ずつ進める練習です。 - スライディングウィンドウで
続いた 1 の 最長を数える0 と 1 だけの並びから、1 がいちばん長く続いた所の長さを返します。並びを 1 回なめながら、いま続いている長さと最長を覚えておく練習です。 - スライディングウィンドウで
幅 k の 平均が 最大の所を探す整数の並びで、続いた k 個の平均がいちばん大きくなる所を探し、その k 個の合計を返します。窓を 1 つずらすたびに、入る数を足して出る数を引く練習です。
スタック
連結リスト
二分探索
木 (DFS と BFS)
深さ優先探索 (DFS) で
二分木の 深さを 求める 二分木の
根から 一番 遠い 葉までの 段の 数を 返す。 左右の 子の 深さを 先に 求めて 1 を 足す、 深さ優先の 再帰の 練習です。 再帰で
2 本の 二分木が 同じか 確かめる 2 本の
二分木を 受け取り、 形も 値も まったく 同じかを 返します。 根を 比べ、 左どうし、 右どうしを 同じ 関数に 任せる、 木の 再帰の いちばん基本の 練習です。 再帰で
二分木を 左右反転する 二分木の
すべての 節で 左の 子と 右の 子を 入れ替え、 鏡に 映した 木を 返します。 下の 木を 先に 反転してから 付け替える、 木の 再帰の 基本の 練習です。 深さ優先探索で
二分木の 根から 葉までの 合計を 調べる 二分木の
根から 葉までの 道で、 値の 合計が 目標の 数に なる物が あるかを 調べる。 残りの 数を 子へ 渡しながら 潜る、 深さ優先の 再帰の 練習です。 再帰で
二分木の いちばん長い道の 長さを 求める 二分木の
中で、 いちばん離れた 2 つの 節を 結ぶ 道の 長さを、 辺の 数で 返します。 下から 高さを 返しながら、 ついでに 最長の 道を 数える、 木の 再帰の 練習です。 再帰で
二分木の 高さが 釣り合っているか 確かめる 二分木の
どの 節でも、 左と 右の 高さの 差が 1 以下かを 返します。 下から 高さを 返し、 崩れを 見つけたら 印を 返して 止める、 木の 再帰の 練習です。 再帰で
二分木の 中に 別の 木と 同じ 部分木が あるか 確かめる 大きい
二分木の どこかの 節から 下が、 小さい 二分木と そっくり 同じかを 返します。 どの 節を 根に するかを 探す再帰と、 2 本の 木が 同じかを 比べる 再帰を 組み合わせる 練習です。
- 深さ優先探索 (DFS) で
二分木の 深さを求める二分木の根から一番遠い葉までの段の数を返す。左右の子の深さを先に求めて 1 を足す、深さ優先の再帰の練習です。 - 再帰で
2 本の 二分木が 同じか確かめる2 本の二分木を受け取り、形も値もまったく同じかを返します。根を比べ、左どうし、右どうしを同じ関数に任せる、木の再帰のいちばん基本の練習です。 - 再帰で
二分木を 左右反転する二分木のすべての節で左の子と右の子を入れ替え、鏡に映した木を返します。下の木を先に反転してから付け替える、木の再帰の基本の練習です。 - 深さ優先探索で
二分木の 根から 葉までの 合計を調べる二分木の根から葉までの道で、値の合計が目標の数になる物があるかを調べる。残りの数を子へ渡しながら潜る、深さ優先の再帰の練習です。 - 再帰で
二分木の いちばん長い 道の 長さを求める二分木の中で、いちばん離れた 2 つの節を結ぶ道の長さを、辺の数で返します。下から高さを返しながら、ついでに最長の道を数える、木の再帰の練習です。 - 再帰で
二分木の 高さが 釣り合っているか確かめる二分木のどの節でも、左と右の高さの差が 1 以下かを返します。下から高さを返し、崩れを見つけたら印を返して止める、木の再帰の練習です。 - 再帰で
二分木の 中に 別の 木と 同じ 部分木が あるか確かめる大きい二分木のどこかの節から下が、小さい二分木とそっくり同じかを返します。どの節を根にするかを探す再帰と、2 本の木が同じかを比べる再帰を組み合わせる練習です。
二分探索木
ヒープ
動的計画法 (DP)
動的計画法
(DP) で 階段の 上り方を 数える 1 段か
2 段ずつ 上る とき、 n 段の 階段の 上り方が 何通り あるかを 数える。 小さな 段の 答えを 覚えて 使い回す、 動的計画の 最初の 練習です。 動的計画法で
通行料つきの 階段を いちばん 安く上る 段ごとに
決まった 通行料を 払うと、 そこから 1 段か 2 段上れる 階段で、 いちばん上へ 抜けるまでの 合計を 最も 安くします。 前の 2 段の 答えだけを 持ち歩く、 階段の 数え方の 続きの 練習です。 動的計画法で
碁盤の 目の 左上から 右下への 道順を 数える 碁盤の
目の 町を、 右か下へ 1 マスずつだけ 進んで 左上から 右下へ 行く 道順が 何通り あるかを 数えます。 上と 左の マスの 答えを 足して 表を 埋める、 2 次元の 動的計画の 入口の 練習です。
- 動的計画法 (DP) で
階段の 上り方を数える1 段か 2 段ずつ上るとき、n 段の階段の上り方が何通りあるかを数える。小さな段の答えを覚えて使い回す、動的計画の最初の練習です。 - 動的計画法で
通行料つきの 階段を いちばん安く上る段ごとに決まった通行料を払うと、そこから 1 段か 2 段上れる階段で、いちばん上へ抜けるまでの合計を最も安くします。前の 2 段の答えだけを持ち歩く、階段の数え方の続きの練習です。 - 動的計画法で
碁盤の 目の 左上から 右下への 道順を数える碁盤の目の町を、右か下へ 1 マスずつだけ進んで左上から右下へ行く道順が何通りあるかを数えます。上と左のマスの答えを足して表を埋める、2 次元の動的計画の入口の練習です。
設計
海外の
そろった問題 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) で 出し入れと 無作為な 取り出しが できる 集合を作る
解いた
言葉で