1. listen / silent -> true
  2. evil / vile -> true
  3. hello / world -> false
  4. different lengths -> false
  5. aA / Aa -> true (同じ文字の多重集合なので大文字小文字を区別しても一致)
  6. empty / empty -> true
  7. aabb / abab -> true
  8. rat / car -> false
コース一覧
コンピューターサイエンス入門:理論編
アナグラム判定

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

アナグラム判定

listen と silent が同じ、と機械に言わせる

listen と silent、evil と vile。人間は並べ替えれば同じだと一目で分かります。これを判定させるとき、まず浮かぶのは「両方を並べ替えて、一致するか見る」というやり方でしょう。

これは正しく動きます。ただし並べ替えには手間がかかります。文字数を n とすると、実用的な並べ替えでも O(n log n)。長い文字列を大量に突き合わせる場面では、この対数ぶんが効いてきます。

そして、そもそも並べ替える必要があるのか、という疑問が残ります。知りたいのは並び順ではなく、どの文字が何個あるか だけのはずです。

並べ替えなくても、数が合っていればよい

レシートと買い物袋の中身を照合する場面を思い浮かべてください。袋から品物を出す順番はどうでもよく、レシートに書かれた個数と袋の中の個数が一致していればいい。文字も同じです。

数え方も工夫できます。片方を +1、もう片方を -1 として同じ帳簿に付ければ、最後にすべてが 0 なら一致です。表を 2 つ作って突き合わせる必要はありません。

Python

diff = 0 diff += 1 # 片方に 1 個あった diff -= 1 # もう片方にも 1 個あった print(diff) # 0 なら釣り合っている

文字ごとにこの帳簿を持てば、1 文字につき 1 回の足し引きで済みます。全体で O(n) になり、並べ替えの log n が消えます。

打ち切れるという利点もあります。ある文字の帳簿がマイナスに転んだ瞬間、それは片方にしか無い文字が出てきたということなので、残りを数える意味がありません。

数える前に落とせるものは、先に落とす

長さが違う 2 つの文字列は、1 文字も数えなくてもアナグラムではありえません。

Python

print(len("listen") == len("silent")) # True print(len("abc") == len("abcd")) # False

長さの取得は一瞬で終わるので、この確認を最初に置くだけで、無駄な集計をまるごと省けます。集合を比べる問題では、この「大きさが違うなら即おしまい」という前置きがたいてい効きます。

a と A は、別の文字

最後に、何を同じとみなすかの取り決めです。

Python

print("a" == "A") # False

プログラムにとって、大文字と小文字は最初から別の文字です。区別するのか、揃えてから比べるのかは仕様の問題であって、どちらかが正しいわけではありません。決まっていないなら、書き始める前に決めてください。空白や記号を無視するかどうかも同じです。「同じとは何か」を曖昧にしたまま書いた判定は、必ずあとで揉めます。

要件

  1. boolean を返す関数 isAnagram(a, b)
  2. map / dict を使い、O(n) で判定する (ソートして比較する O(n log n) は避ける)
  3. 大文字小文字は区別する。長さが違うなら即 false

入出力例

isAnagram("listen", "silent") → true isAnagram("evil", "vile") → true isAnagram("hello", "world") → false isAnagram("abc", "abcd") → false isAnagram("aA", "Aa") → true isAnagram("", "") → true isAnagram("aabb", "abab") → true isAnagram("rat", "car") → false

ヒント

a で +1、b で -1 して、途中でマイナスになったら即 false で打ち切る

最初に長さチェックを入れると、不要な集計を省ける

Python なら counts.get(ch, 0) で安全に初期値を補える

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

関連レッスン

  • 第 4 章クイズ — データ構造 (基本)

    スタック / キュー / set / map の基本性質と計算量を 4 択で総まとめする。

  • バイト → KB 変換

    1024 で割って KB に変換し、容量表示の基本を体得する

  • Base64 エンコード後の長さ計算

    バイト列を Base64 エンコードしたときの文字数を、入力長から数式で求める関数を作ります。

  • 重複データを 1NF に変換 (フラットなリスト化)

    1 セルに複数値が詰め込まれた CSV 風データを、1 行 = 1 値にフラット化する第一正規形(1NF)の変換を実装します。

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

メモ

アナグラム判定

⌘S で保存