Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonでリスト内の重複要素を検出するプログラム ― O(n)時間・定数空間の解法

サイズが n + 1 の整数リスト nums があり、その要素はすべて範囲 1, 2, ..., n の中から選ばれているとします。

このとき、鳩の巣原理(Pigeonhole Principle)より、リスト内には必ず少なくとも1つの重複した値が存在します。この重複している要素を見つけるのが本記事の目的です。

さらに、ここでは計算量 O(n)・追加メモリ O(1)(定数空間)という制約のもとで解くことを目標とします。

問題の例

たとえば、入力が次のような場合を考えてみましょう。

nums = [2, 1, 4, 3, 5, 4]

この場合、重複している値は 4 なので、出力は 4 となります。

解法の考え方

この問題は「合計値の差」を使うことで、ソートやハッシュセットなしに効率的に解けます。手順は以下の通りです。

  • q : リスト nums 内の全要素の合計値

  • n : リスト nums のサイズ

  • v : (n - 1) * n / 2 の小数点以下切り捨て値(=1から n-1 までの総和)

  • q - v を返す(これが重複要素となる)

なぜこれで重複が見つかるのか?

リストのサイズは n + 1 ですが、実際に使われる値は 1 から n-1 までの範囲です。もし重複がなければ、リストの合計は 1 + 2 + ... + (n-1) = (n-1) * n / 2 になるはずです。

しかし実際には1つ余分な要素(重複分)が含まれているため、実際の合計から理論上の合計を引いた差が、そのまま重複要素の値になります。

Pythonでの実装例

それでは、実際のコードを見てみましょう。

def solve(nums):
   q = sum(nums)
   n = len(nums)
   v = (n - 1) * (n) // 2
   return q - v

nums = [2, 1, 4, 3, 5, 4]
print(solve(nums))

入力

[2, 1, 4, 3, 5, 4]

出力

4

まとめ

この手法は、リストを走査して合計を取るだけなので時間計算量 O(n)、変数を数個使うだけで済むため空間計算量 O(1) を満たします。ソート(O(n log n))やハッシュセット(O(n) の追加メモリ)を使わずに済むため、メモリ制約が厳しい場面でも有効なアプローチです。

  1. リスト内の要素の合計を求めるPythonプログラム

    この記事では、Pythonを使ってリスト内のすべての要素の合計を求める方法について、具体的なコード例とともに解説します。問題の定義リストが入力として与えられたとき、そのリストに含まれるすべての要素の合計値を計算する必要があります。例えば、[1, 2, 3, 4, 5]というリストが与えられた場合、出力は 15(1+2+3+4+5)となります。この問題を解くためのアプローチは主に2つあります。1つは組み込み関数を使用する方法、もう1つはブルートフォース(総当たり)方式でループ処理を行う方法です。方法1:組み込み関数 sum() を使うPythonには標準で用意されている組み込み関数 sum()

  2. PythonでリストからN個の最大要素を取得する方法

    整数のリストが与えられたとき、その中からN個の大きな要素を取り出して新しいリストとして返すのが、ここでの課題です。本記事では、基本的なループ処理による方法から、Python標準ライブラリを活用した効率的な方法まで、サンプルコードとともに解説します。 例 入力 : [40, 5, 10, 20, 9] N = 2 出力 : [40, 20] アルゴリズム 整数のリストと、取得する要素数Nを受け取ります。 N回のループを実行します。 各ループでリスト内の最大値を探し、新しいリストに格納すると同時に元のリストから削除します。 実装コード def Nnumberele(list1, N):