辞書で同じ文字でできた語を組に分ける

文字を並べ替えると同じになる語どうしを、1 つの組にまとめます。語ごとに文字の数を数えた物を辞書の鍵にして、同じ鍵の語を集める練習です。

海外で定番の問題リスト 4 本のうち 3 本に入っています (Blind 75、NeetCode 150、LeetCode Top Interview 150)

問題

英小文字の語の並び strs を受け取ります。文字を並べ替えると同じ語になるものどうし (使う文字とその数がまったく同じもの) を 1 つの組にまとめ、組の並びを返す関数を書いてください。

  • 返す順は次のとおりに決めます。組の中の語は strs に出てきた順に並べます。組どうしは、その組の語が strs に初めて出てきた順に並べます
  • 同じ語が 2 回あれば、2 つとも同じ組に入れます。空の語 "" も 1 つの語として扱います
  • strs の長さは 1 以上 10000 以下、語の長さは 0 以上 100 以下で、使う文字は a から z だけです

入力と出力の例

例 1

strs = ["stop", "pots", "melon", "lemon", "tops"]
[["stop", "pots", "tops"], ["melon", "lemon"]]

例 2

使う文字の種類が同じでも、数が違えば別の組です。

strs = ["aab", "abb", "bab", "baa"]
[["aab", "baa"], ["abb", "bab"]]

例 3

空の語どうしも 1 つの組になります。

strs = ["", "b", ""]
[["", ""], ["b"]]

面接での聞かれ方

面接では、例を 1 つ見せて、短く聞かれることが多いです。

  • 「文字を入れ替えると同じになる単語どうしをグループにしてください」
  • 「2 つの語が同じ組かを、どうやって調べますか?」と、比べ方を先に聞かれます
  • 書き終えたあとに「1 語の長さが長いとき、もっと速くできますか?」と、鍵の作り方を詰められます
  • 「大文字や記号が混ざったら?」と、文字の種類を広げた場合を聞かれることもあります

返す順をどうするかは、問題文に無ければ先に確かめます。ここでは、出てきた順を保つと決めてあります。

ヒント

まだ開いていません

付箋は 4 枚。下の段ほど答えに近づきます

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

アルゴリズムのチートシートの「ハッシュマップ」に、この型の要点を表とコードでまとめています。

ハッシュは、値から番地を計算して、探す手間をほぼ 1 回にする仕組みです。重複や回数の問題は、この形で解けます。

main.py
def group_anagrams(strs: list[str]) -> list[list[str]]:
    """
    Goal: 何を返すか

    idea1: まず思いつく案
    -> runtime: O(?)  space: O(?)

    idea2: もっと速い案
    -> runtime: O(?)  space: O(?)

    edge case: 空、1 つだけ、など
    """
    # ここに書きます
    pass


# 「実行」を押すと、この行の結果が出ます
print(group_anagrams(["stop", "pots", "melon", "lemon", "tops"]))

できているか「例で確かめる」を押すと、問題の例を全部この関数に渡して、通ったかをここに出します