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

Pythonで1からNまでの範囲の欠落している数字をすべて見つけるプログラム

サイズ n の整数リスト nums があり、リスト内のすべての数値は区間 [1, n] に含まれているとします。このとき、一部の要素は2回出現し、その他は1回だけ出現します。この課題では、[1, n] の範囲のうちリストに存在しない数値(欠落している数字)をすべて見つけ、昇順に並べて返す必要があります。できるだけ線形時間 O(n) で動作する効率的な解法を目指しましょう。

例えば、入力が [4, 4, 2, 2, 6, 6] の場合、出力は [1, 3, 5] となります。

解法のアプローチ

この問題は「カウント配列(各数値の出現回数を記録する配列)」を使うことでシンプルに解決できます。手順は以下のとおりです。

  • ステップ1: サイズが len(nums) + 1 の配列 arr を作成し、すべての要素を 0 で初期化します。
  • ステップ2: リスト nums 内の各数値 i について、arr[i] の値を 1 ずつ増やします。これにより、各数値の出現回数が記録されます。
  • ステップ3: 結果を格納するための空のリスト missing を用意します。
  • ステップ4: インデックス i を 0 から arr の末尾まで走査し、arr[i] が 0(=一度も出現していない)かつ i が 0 でない場合、i を missing の末尾に追加します。
  • ステップ5: 最後に missing を返します。

それでは、実際の実装例を見て理解を深めましょう。

実装例

class Solution:
   def solve(self, nums):
      arr = [0]*(len(nums)+1)
      for i in nums:
         arr[i] += 1
      missing = []
      for i in range(len(arr)):
         if arr[i] == 0 and i != 0:
            missing.append(i)
      return missing
ob = Solution()
print(ob.solve([4, 4, 2, 2, 6, 6]))

入力

[4, 4, 2, 2, 6, 6]

出力

[1, 3, 5]

計算量のポイント

この解法では、リストの走査とカウント配列の確認の両方に O(n) かかるため、全体の時間計算量は O(n) です。ただし、補助配列 arr を使用しているため、空間計算量は O(n) となります。もし「追加メモリを使わない(定数空間)」という要件を厳密に満たしたい場合は、各値 v を参照した際に nums[v-1] の符号を負に反転させるテクニックなどを活用することで、追加の配列なしで欠落した数字を検出することも可能です。

  1. 【Python】リスト内の2つの数値を足して合計がkになるペアを探すプログラム

    数値のリスト nums ともう一つの数値 k が与えられたとき、リスト内の任意の2つの数値を足した合計が k と一致するかどうかを判定するプログラムを作成します。ただし、同じ要素を2回使用することはできません。また、数値には負の数や0が含まれる場合もあります。例えば、入力が nums = [45, 18, 9, 13, 12]、k = 31 の場合、18 + 13 = 31 となるため、出力は True になります。解法のアプローチこの問題は「セット(集合)」を使うことで効率的に解けます。各数値に対して、それとペアになるべき値(k - num、いわゆる補数)を事前にセットへ記録しておき、後から

  2. Pythonで1〜Nの範囲の配列から欠落している4つの数を検索する方法

    問題の概要ここでは、1からNまでの範囲に属する相異なる整数で構成された配列を扱います。配列のサイズは N-4 であり、要素の重複は一切ありません。つまり、1からNまでのうち4つの数が配列から抜け落ちていることになります。この記事では、その4つの欠落数を昇順で特定する方法を解説します。例として、入力が A = [2, 8, 4, 13, 6, 11, 9, 5, 10] の場合、出力は [1, 3, 7, 12] となります。アルゴリズムのポイントこの問題は、追加のメモリをほとんど使わずに解決できます。鍵となるのは「符号反転」のテクニックです。配列内の値 v に対応する位置(インデックス v-1