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

C#で組み込み関数を使わずにソート済み配列から欠落した数値を見つける3つの方法

C#では、組み込み関数に頼らなくても、いくつかのアルゴリズム的なアプローチによってソート済み配列の中から欠落している数値を効率的に特定できます。本記事では、代表的な3つの方法を具体的なコード例とともに解説します。

方法1:等差数列の和の公式を利用する

0からnまでの連続する整数の合計は、有名な公式「n(n+1)/2」で求めることができます。まず配列の要素数からこの公式で理論上の合計値を算出し、次に実際に配列内の全要素を足し合わせた値を求めます。この2つの差分こそが、欠落している数値です。

  • 計算量:O(n)
  • 追加メモリ:不要(O(1))

方法2:ブール型の補助配列を使用する

元の配列の要素数 + 1 のサイズを持つbool型の新しい配列を作成します。元の配列全体を走査しながら、出現した数値に対応するインデックスの値をtrueに設定していきます。最後までfalseのまま残っているインデックスが、欠落している数値を示しています。

  • 計算量:O(n)
  • 追加メモリ:補助配列分が必要(O(n))

方法3:XOR(排他的論理和)演算を利用する

XOR演算には「同じ値同士を演算すると0になる」「0との演算では値が変わらない」という性質があります。この性質を利用して配列全体を順にXORで処理すると、ペアにならない数値、すなわち欠落している数値だけが最終的に残ります。

  • 計算量:O(n)
  • 追加メモリ:不要(O(1))

サンプルコード

using System;
namespace ConsoleApplication{
    public class Arrays{
        public int MissingNumber1(int[] arr){
            int totalcount = 0;
            for (int i = 0; i < arr.Length; i++){
                totalcount += arr[i];
            }
            int count = (arr.Length * (arr.Length + 1)) / 2;
            return count - totalcount;
        }
        public int MissingNumber2(int[] arr){
            bool[] tempArray = new bool[arr.Length + 1];
            int element = -1;
            for (int i = 0; i < arr.Length; i++){
                int index = arr[i];
                tempArray[index] = true;
            }
            for (int i = 0; i < tempArray.Length; i++){
                if (tempArray[i] == false){
                    element = i;
                    break;
                }
            }
            return element;
        }
        public int MissingNumber3(int[] arr){
            int result = 1;
            for (int i = 0; i < arr.Length; i++){
                result = result ^ arr[i];
            }
            return result;
        }
    }
    class Program{
        static void Main(string[] args){
            Arrays a = new Arrays();
            int[] arr = { 0, 1, 3, 4, 5 };
            Console.WriteLine(a.MissingNumber1(arr));
            Console.WriteLine(a.MissingNumber2(arr));
            Console.WriteLine(a.MissingNumber3(arr));
            Console.ReadLine();
        }
    }
}

実行結果

2
2
2

この例では、配列 { 0, 1, 3, 4, 5 } から数値「2」が欠落しているため、3つのメソッドすべてが正しく「2」を出力します。

まとめ

メモリ効率を重視するなら和の公式またはXOR演算、実装のわかりやすさやデバッグのしやすさを重視するならブール配列方式がおすすめです。配列のサイズや要件に応じて、最適な手法を選択しましょう。

  1. C#のArrayクラスのプロパティとは?主要プロパティと使い方を解説

    C#におけるArrayクラスは、すべての配列の基底クラスであり、System名前空間で定義されています。このクラスには、配列のサイズや読み取り専用かどうか、次元数などの情報を取得するための便利なプロパティが多数用意されています。Arrayクラスの主なプロパティ一覧No.プロパティと説明1IsFixedSize配列が固定サイズであるかどうかを示す値を取得します。2IsReadOnly配列が読み取り専用であるかどうかを示す値を取得します。3Length配列のすべての次元に含まれる要素の総数を、32ビット整数(int)として取得します。4LongLength配列のすべての次元に含まれる要素の総数を、

  2. Pythonで連続する番号のソート済み配列から欠落した要素を見つける方法

    問題の概要 n個の重複しない数値からなる配列Aを考えます。これらの要素は昇順に並んでいますが、そのうち1つだけが欠落しています。この欠落している要素を効率的に見つけ出すのが課題です。 例えば、入力が A = [1, 2, 3, 4, 5, 6, 7, 9] のような場合、出力は 8 となります。 解決の手順(アルゴリズム) 配列がソート済みであるという特性を活かし、二分探索を用いることでこの問題を解決できます。連続した数列では、欠落が発生していない位置のインデックスiに対して「A[i] − i == A[0]」という関係が常に成り立ちます。この性質を利用して、欠落位置を絞り込んでいきます。