集合で 並べ替えずに 1 ずつ続く 数の 最長を求める
ばらばらに
海外で定番の問題リスト 4 本には入っていません
問題
あるnums で
番号が 1 ずつ続いた
- 並びの
中の 位置は 関係 ありません。 値だけを 見て、 1 ずつ続いているかを考えます - 同じ
番号は 1 日として数えます numsが空なら 0 を返します numsの長さは 0 以上 100000 以下で、 値は -1000000000 以上 1000000000 以下です - 並べ替えを
使わず、 時間が O(n) の 書き方に してください
入力と出力の例
例 1
2、
例 2
5 と 7 が 2
例 3
空の
面接での聞かれ方
面接では、
- 「並べ替えずに、
O(n) で 最長の 連続した 数の 長さを 求めてください」 - 「同じ数は入りますか?」と、
自分から 確かめるかを 見られます - 先に
並べ替えの 答えを 言わせてから、 「O(n) に できますか?」と 詰められる こともあります
並べ替えなら O(n log n) ですぐ
ヒント
まだ開いていません
付箋は 4 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3
ヒント 4答えに近い
アルゴリズムのチートシートの「ハッシュマップ」に、
関わる学び
ハッシュは、
まず 考える手順
段 1
素直に
段 2
値を
段 3
数え
段 4
繰り返しは、
解答
Python
Python
def longest_streak(nums):
have = set(nums)
best = 0
for x in have:
if x - 1 in have:
continue
y = x
while y + 1 in have:
y += 1
size = y - x + 1
best = max(best, size)
return bestJavaScript
JavaScript
function longestStreak(
nums
) {
const have = new Set(nums);
let best = 0;
for (const x of have) {
if (have.has(x - 1)) {
continue;
}
let y = x;
while (have.has(y + 1)) {
y++;
}
const size = y - x + 1;
best = Math.max(best, size);
}
return best;
}Go
Go
func longestStreak(
nums []int,
) int {
have := map[int]bool{}
for _, x := range nums {
have[x] = true
}
best := 0
for x := range have {
if have[x-1] {
continue
}
y := x
for have[y+1] {
y++
}
best = max(best, y-x+1)
}
return best
}x - 1 がy をy がy - x + 1 です。true への map でfalse と
計算量
- 時間は O(n) です。
集合を 作るのに O(n)、 どの 値も 「先頭か」の 確かめで 1 回、 続きを たどるので 1 回見られるだけです - 使う
記憶は O(n) です。 集合に、 違う 値の 数だけ入ります - 段 1 の
並べ替えの 書き方は、 時間が O(n log n) です。 全部の 値から 数える 書き方は、 続きが 長いと O(n²) です
よく ある間違い
- 先頭か
どうかを 確かめずに、 全部の 値から数える。 答えは 合いますが、 1 から 10 万までのような 長い 続きで、 たどる 回数が O(n²) に なります。 x - 1が無い 値からだけ数えます - 元の
並びで 繰り返す。 同じ 先頭の 値が たくさん 入っていると、 同じ 続きを 何回も たどります。 集合の 方で回します - 並べ替えた
あと、 同じ値で 続きを切る。 例 2 で 5、 5 の ところで 数え直すと、 4 ではなく 3 を 返します。 同じ値は 読み飛ばします - 空の
並びで、 best を 1 から始める。 例 3 で 1 を 返します。 0 から始めます
解答を動かした版 Python 3.14.7Node.js 24.22.1Go 1.24.2確認日 2026年11月8日
面接での 話し方の例
書き始める
「並べ替えれば O(n log n) で
書けますが、 O(n) に するなら 集合を 使います。 値を 全部 集合に 入れ、 x - 1 が 無い値だけを 続きの 先頭として、 x + 1、 x + 2 と 集合を たどって 長さを 数えます。 どの 値もたどられるのは 1 回だけなので、 時間も 記憶も O(n) です。 同じ値は 集合が 1 つに まとめます。」
書き終えたら、
「例 1 で
たどります。 12、 3、 11、 4、 13 は 1 小さい 値が あるので 飛ばします。 2 は 1 が 無いので 先頭で、 3、 4 と たどって 長さ 3。 10 も 先頭で、 11、 12、 13 と たどって 長さ 4 です。 大きい方の 4 を 返します。」