問題
整数のnums をnums の
- 位置が
違っても 値が 同じなら、 同じ値と みなします。 5と-5は別の値です numsの長さは 1 以上 100000 以下、 値は どれも 絶対値が 10 億以下です
入力と出力の例
例 1
入力
nums = [4, 9, 2, 9, 7]出力
true例 2
入力
nums = [15, -3, 8, 0]出力
false例 3
同じ
入力
nums = [-7, 7, 0, 3, -7]出力
true面接での聞かれ方
面接の
- 「整数の
配列に 重複が あるかを 返してください」 - 書き終えた
あとに 「計算量は?」 「メモリを 使わずに 解くと どうなりますか?」と、 時間と 記憶の 取り 引きを 聞かれます - 「重複が
見つかったら、 すぐに 止められますか?」と、 早く 打ち 切れるかを 聞かれる こともあります
答えは
アルゴリズムのチートシートの「ハッシュマップ」に、この型の要点を表とコードでまとめています。
まず 考える手順
段 1
まずは
段 2
並べ替えると、
段 3
さらにset、Set、map) を
解答
Python
Python
def has_duplicate(nums):
seen = set()
for x in nums:
if x in seen:
return True
seen.add(x)
return FalseJavaScript
JavaScript
function hasDuplicate(nums) {
const seen = new Set();
for (const x of nums) {
if (seen.has(x)) {
return true;
}
seen.add(x);
}
return false;
}Go
Go
func hasDuplicate(
nums []int,
) bool {
seen := map[int]bool{}
for _, x := range nums {
if seen[x] {
return true
}
seen[x] = true
}
return false
}重複が
計算量
- 時間は O(n) です。
並びを 前から 1 回なめ、 集合を 調べるのも 足すのも、 平均して 一定の 手間で済みます - 使う
記憶は O(n) です。 重複が 無い ときは、 全部の 値を 集合に覚えます - 段 2 の
並べ替えの 書き方は、 時間が O(n log n) で、 元の 並びを その場で 並べ替えるなら 記憶は O(1) に 近くなります。 記憶を 使う 代わりに 時間を 縮めた、という 取り引きです
よく ある間違い
- 並びを
集合に 変えて 長さを 比べるだけにする。 len(set(nums)) != len(nums)も正しく 動きますが、 重複が 先頭に あっても 全部の 値を 集合に 入れ終わるまで 止まりません。 「すぐに 止められますか?」と 聞かれたら、 1 つずつ足す 書き方に 直せるように しておきます - 並べ替えの
書き方で、 元の 並びを 黙って 並べ替える。 呼んだ側の 並びが 変わってしまいます。 並べ替えて よいかを 面接官に 確かめるか、 写しを 作って 並べ替えます (写しを 作るなら 記憶は O(n) です) - 先に
集合へ 足してから調べる。 seen.add(x)をifより前に 置くと、 いま足したばかりの 自分を 見つけて、 どの 並びでも 最初の 値で 真を 返します。 「調べてから足す」の 順を守ります
解答を動かした版 Python 3.12.14Node.js 22.23.4Go 1.24.6確認日 2026年10月30日
面接での 話し方の例
書き始める
「全部の
組を 比べれば O(n²) で、 並べ替えて 隣を 比べれば O(n log n) です。 見た 値を 集合に 覚えておけば、 出てきた 値が 前に あったかを 一定の 手間で 調べられるので、 1 回なめるだけの O(n) に なります。 その 代わり、 記憶を O(n) 使います。 重複が 見つかれば その 場で 止めます。」
書き終えたら、
「例 1 の
[4, 9, 2, 9, 7]でたどります。 4、 9、 2 は どれも 集合に 無いので 足していきます。 4 つ目の 9 は 集合に もう あるので、 そこで 真を 返します。 最後の 7 は 見ません。」
