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

【JavaScript】配列内の奇数回出現する整数をXOR演算で見つける方法


整数の配列が与えられ、「ある1つの要素を除いて、すべての要素が偶数回出現する」という条件が課せられます。私たちの課題は、その例外となる要素をたった1回の反復処理で見つけ出すことです。

ここでは、次のサンプル配列を使って考えてみましょう。

[1, 4, 3, 4, 2, 3, 2, 7, 8, 8, 9, 7, 9]

この配列では、1だけが1回(奇数回)出現し、それ以外の4、3、2、7、8、9はすべて2回(偶数回)出現しています。人間の目で見れば答えはすぐ分かりますが、プログラムで効率よく求めるにはどうすればよいのでしょうか。

XOR(排他的論理和)演算子の基礎知識

この問題を解く鍵となるのが、ビット演算子であるXOR(^)です。まずはその動作を理解しておきましょう。

XOR演算子は、2つのオペランドが互いに異なる値の場合にTRUE(1)を返し、同じ値の場合にはFALSE(0)を返します。

XOR演算子の真理値表

0 ^ 0 → 0
0 ^ 1 → 1
1 ^ 0 → 1
1 ^ 1 → 0

この動作を注意深く観察すると、重要な性質に気づきます。まったく同じ値同士のXOR演算(例:12 ^ 12)は常にFALSE、つまり0を返すのです。言い換えると、「偶数回出現した値はXORによって打ち消される」ということになります。そして、これこそまさに私たちが求めている性質です。

reduceメソッドを使った実装

この性質を応用すると、Array.prototype.reduce()メソッドを使って非常に簡潔にコードを書くことができます。

コード例

const sampleArray = [1, 4, 3, 4, 2, 3, 2, 7, 8, 8, 9, 7, 9];
console.log(sampleArray.reduce((a, b) => a ^ b));

仕組みの解説

このコードは配列の各要素を順番に走査しながら、累積的にXOR演算を適用していきます。XORには結合法則交換法則が成り立つため、要素の出現順序に関係なく、偶数回出現する要素は互いに打ち消し合って0になり、最終的に残るのは奇数回出現する唯一の要素だけです。

このアプローチの優れた点は、計算コストの低さにあります。

  • 時間計算量:O(n) — 配列を1回走査するだけで完了
  • 空間計算量:O(1) — 追加の記憶領域がほぼ不要

ハッシュマップやSetを使って各要素の出現回数をカウントする方法もありますが、それらは追加のメモリを消費します。XORを使う手法は、余分なデータ構造なしに1回の反復で解決できる点が大きな魅力です。

実行結果

上記のコードを実行すると、コンソールには以下のように出力されます。

1

見事に、奇数回出現する要素「1」だけが取り出されました。このテクニックはコーディング面接でも頻出の定番問題なので、XORの性質と合わせてぜひマスターしておきましょう。

  1. JavaScriptで配列内の最頻値とその出現回数を求める方法

    JavaScriptでは、リテラル(数値や文字列など)を含む配列を受け取り、その中で最も多く登場する要素(最頻値)と、それが何回繰り返されているかを出力する関数を書くことができます。実装の考え方この処理は、配列の reduce() メソッドを使うことで効率的に実装できます。各要素の出現回数をオブジェクトに記録しながら走査し、同時に最大出現回数を持つ要素を追跡します。同じ出現回数の要素が複数ある場合は、それらすべてを配列に格納して返すようにしています。コード例実際のコードは以下のとおりです。 count[acc[0]]) { return [val]; }

  2. JavaScriptで配列内の出現回数が2番目に多い要素を取得する方法

    この記事では、リテラル値の配列を受け取り、その中で出現回数が2番目に多い要素を返すJavaScript関数の実装方法を解説します。問題の概要例として、入力配列が以下の場合を考えてみましょう。const arr = [2, 5, 4, 3, 2, 6, 5, 5, 7, 2, 5];この配列では、5が4回、2が3回出現しています。つまり、最も多く出現する要素は5であり、2番目に多く出現する要素は2です。したがって、期待される出力は次のようになります。const output = 2;アルゴリズムの流れ空のオブジェクト(マップ)を作成し、各要素の出現回数を記録します。配列を走査しながら、各要素のカ