Back to Bit Manipulation
Find Original Array of Prefix XOR
Find Original Array of Prefix XOR
š§© Problem Statement
You are given an integer array pref of size n. Find and return the array arr of size n that satisfies:
pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i].
Note thatarr[0] ^ ... ^ arr[i]denotes the bitwise-XOR of the firsti + 1non-negative integers.
š¹ Example 1:
Input:
pref = [5,2,0,3,1]
Output:
[5,7,2,3,2]
Explanation:
pref[0] = 5=>arr[0] = 5pref[1] = 5 ^ 7 = 2=>arr[1] = 7pref[2] = 5 ^ 7 ^ 2 = 0=>arr[2] = 2pref[3] = 5 ^ 7 ^ 2 ^ 3 = 3=>arr[3] = 3pref[4] = 5 ^ 7 ^ 2 ^ 3 ^ 2 = 1=>arr[4] = 2
š¹ Example 2:
Input:
pref = [13]
Output:
[13]
š Approaches
1. Inverse XOR (Single Pass)
- Property: If
C = A ^ B, thenB = A ^ CandA = B ^ C(XOR is its own inverse). - Given:
pref[i] = pref[i-1] ^ arr[i](wherepref[-1] = 0). - Derivation:
arr[i] = pref[i] ^ pref[i-1]. - Base Case:
arr[0] = pref[0]. - Algorithm:
arr[0] = pref[0]- For
i > 0,arr[i] = pref[i] ^ pref[i-1].
ā³ Time & Space Complexity
- Time Complexity: $O(N)$
- Space Complexity: $O(1)$ (ignoring output space).
š Code Implementations
C++
#include <vector>
#include <iostream>
using namespace std;
class Solution {
public:
vector<int> findArray(vector<int>& pref) {
int n = pref.size();
vector<int> arr(n);
arr[0] = pref[0];
for (int i = 1; i < n; ++i) {
arr[i] = pref[i] ^ pref[i-1];
}
return arr;
}
};
Python
from typing import List
class Solution:
def findArray(self, pref: List[int]) -> List[int]:
n = len(pref)
arr = [0] * n
arr[0] = pref[0]
for i in range(1, n):
arr[i] = pref[i] ^ pref[i-1]
return arr
Java
class Solution {
public int[] findArray(int[] pref) {
int n = pref.length;
int[] arr = new int[n];
arr[0] = pref[0];
for (int i = 1; i < n; i++) {
arr[i] = pref[i] ^ pref[i-1];
}
return arr;
}
}
š Real-World Analogy
Reconstructing Daily Steps:
Imagine your smartwatch only stores the "Total Steps Taken" since you bought it.
pref[i]is the total steps on Dayi.- You want to find out how many steps you walked specifically on Day
i. - You take the total for Day
iand "undo" the total for Dayi-1. In XOR world, "undoing" addition (accumulation) is done by XORing again.
Decrypting a Message Stream:
Imagine a stream cipher where each character is XORed with a cumulative key. To recover the original message (array), you need to "undo" the XOR operation using the previous state (prefix).
šÆ Summary
ā XOR Inverse: Knowing the current cumulative state and the previous cumulative state allows you to deduce the current input.
Solution Code
O(n) TimeO(1) Space
#include <iostream>
#include <vector>
using namespace std;
class Solution {
public:
vector<int> findArray(vector<int> &pref) {
int n = pref.size();
vector<int> arr(n);
arr[0] = pref[0];
for (int i = 1; i < n; ++i) {
arr[i] = pref[i] ^ pref[i - 1];
}
return arr;
}
};
int main() {
Solution sol;
vector<int> pref1 = {5, 2, 0, 3, 1};
vector<int> res1 = sol.findArray(pref1);
cout << "Test Case 1: ";
for (int x : res1)
cout << x << " "; // Expect 5 7 2 3 2
cout << endl;
vector<int> pref2 = {13};
vector<int> res2 = sol.findArray(pref2);
cout << "Test Case 2: ";
for (int x : res2)
cout << x << " "; // Expect 13
cout << endl;
return 0;
}
SYSTEM STABLEUTF-8 ⢠STATIC_RENDER