集合で並べ替えずに 1 ずつ続く数の最長を求める

ばらばらに並んだ整数から、1 ずつ続いて並べられる数の、いちばん長い続きの長さを求めます。値を集合に入れ、続きの先頭の数からだけ数えて O(n) にする、ハッシュの練習です。

海外で定番の問題リスト 4 本には入っていません

問題

ある人が勉強会に来た日の番号を、整数の並び nums で受け取ります。並びは来た順ではなく、ばらばらです。同じ日の番号が 2 回以上入っていることもあります。

番号が 1 ずつ続いた日の組 (たとえば 7、8、9) のうち、いちばん長い物の日数を返す関数を書いてください。

  • 並びの中の位置は関係ありません。値だけを見て、1 ずつ続いているかを考えます
  • 同じ番号は 1 日として数えます
  • nums が空なら 0 を返します
  • nums の長さは 0 以上 100000 以下で、値は -1000000000 以上 1000000000 以下です
  • 並べ替えを使わず、時間が O(n) の書き方にしてください

入力と出力の例

例 1

2、3、4 の 3 日と、10、11、12、13 の 4 日の 2 つの続きがあります。長いのは 4 日の方です。

nums = [12, 3, 11, 4, 13, 2, 10]
4

例 2

5 と 7 が 2 回ずつ入っていますが、1 日と数えます。5、6、7、8 の 4 日です。

nums = [5, 5, 6, 8, 7, 7]
4

例 3

空の並びです。

nums = []
0

面接での聞かれ方

面接では、並べ替えを禁じる形で渡されることがよくあります。

  • 「並べ替えずに、O(n) で最長の連続した数の長さを求めてください」
  • 「同じ数は入りますか?」と、自分から確かめるかを見られます
  • 先に並べ替えの答えを言わせてから、「O(n) にできますか?」と詰められることもあります

並べ替えなら O(n log n) ですぐ書けるので、まずそれを口に出してから、O(n) へ縮める道筋を話すと伝わりやすくなります。

ヒント

まだ開いていません

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

  1. ヒント 2

  2. ヒント 3

  3. ヒント 4答えに近い

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

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

main.py
def longest_streak(nums: list[int]) -> int:
    """
    Goal: 何を返すか

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

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

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


# 「実行」を押すと、この行の結果が出ます
print(longest_streak([12, 3, 11, 4, 13, 2, 10]))

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