PythonでXORエンコードされた配列から元の配列を復元するプログラム
問題の概要
非負の整数n個からなる隠し配列 arr があるとします。この配列は、長さ n-1 の別の配列 enc にエンコードされており、その規則は次の通りです。
enc[i] = arr[i] XOR arr[i+1]
ここで、エンコード済みの enc 配列と、元の配列の最初の要素を表す整数 first が与えられたとき、元の配列全体を復元することが目標となります。
例えば、入力が enc = [8,3,2,7]、first = 4 の場合、出力は [4, 12, 15, 13, 10] になります。
解法のポイント:XORの性質
この問題は、XOR演算の以下の性質を利用すると簡単に解けます。
- 自己消去: a XOR a = 0(同じ値同士のXORは0になる)
- 単位元: a XOR 0 = a(0とのXORでは値が変わらない)
- 可逆性: (a XOR b) XOR b = a(同じ値で2回XORすると元に戻る)
関係式 enc[i] = arr[i] XOR arr[i+1] の両辺に arr[i] をXORすると、次のように変形できます。
arr[i] XOR enc[i] = arr[i] XOR arr[i] XOR arr[i+1] = 0 XOR arr[i+1] = arr[i+1]
つまり、「前の要素」と「エンコード値」のXORを取ることで、次の要素が一意に求まります。この計算を先頭から順に繰り返せば、first を起点として配列全体を復元できるのです。
アルゴリズムの手順
arrをfirstのみを含む配列として初期化する- i を 0 から
encのサイズ - 1 まで繰り返す:arr[i] XOR enc[i]の結果をarrの末尾に追加する
arrを返す
Pythonでの実装例
以下のコードで実際の動作を確認してみましょう。
def solve(enc, first):
arr = [first]
for i in range(0, len(enc)):
arr.append(arr[i] ^ enc[i])
return arr
enc = [8,3,2,7]
first = 4
print(solve(enc, first))
入力
[8,3,2,7], 4
出力
[4, 12, 15, 13, 10]
計算量の評価
このアルゴリズムは配列を一度だけ走査するため、時間計算量は O(n) です。また、結果を格納するために O(n) の追加メモリを使用します。エンコード値から各要素が一意に決まるため、これ以上効率化の余地はなく、本質的に最適な解法と言えます。
-
Pythonで挿入ソート(Insertion Sort)を実装する方法:アルゴリズムとサンプルコードを徹底解説
この記事では、Python 3.x(およびそれ以前のバージョン)における挿入ソートの実装方法について詳しく解説します。挿入ソートは、トランプの手札を整理するイメージに近い、直感的で理解しやすいソートアルゴリズムです。挿入ソートのアルゴリズム挿入ソートは以下の手順で動作します。入力要素を順番に走査し、各反復ごとにソート済みの配列部分を少しずつ拡張していきます。現在注目している要素(キー)を、ソート済み部分の中で最も大きい値と比較します。キーがその値より大きければ、要素は元の位置のまま次の要素へ進みます。そうでなければ、ソート済み配列内の正しい位置を探し出し、そこへ移動させます。具体的には、ソート
-
Pythonで学ぶ挿入ソート(Insertion Sort)の仕組みと実装方法
この記事では、Python 3.xにおける挿入ソート(Insertion Sort)の基本的な考え方と、実際のコードによる実装方法をわかりやすく解説します。 挿入ソートのアルゴリズム 挿入ソートは、配列を「整列済みの部分」と「未整列の部分」に分け、未整列の要素を一つずつ取り出して、整列済み部分の正しい位置に挿入していくシンプルなソート手法です。処理の手順は以下の通りです。 1. 各反復ごとに整列済みの配列を少しずつ拡大しながら、入力要素を走査する。 2. 現在の要素(キー)を、整列済み配列内の最大値と比較する。 3. キーがその最大値より大きければ、要素はそのままの位置に置かれ、 次の要