Given an array arr[] of size n, construct another array res[] of size n such that res[i] is equal to the XOR of all elements of arr[] except arr[i].
Examples:
Input: arr[] = [2, 1, 5, 9]
Output: [13, 14, 10, 6]
Explanation:
res[0] = 1 ^ 5 ^ 9 = 13
res[1] = 2 ^ 5 ^ 9 = 14
res[2] = 2 ^ 1 ^ 9 = 10
res[3] = 2 ^ 1 ^ 5 = 6
Therefore, the resulting array is [13, 14, 10, 6].
Input: arr[] = [2, 1]
Output: [1, 2]
Explanation:
res[0] = 1
res[1] = 2
Since only one element remains after excluding the current element, each position contains that remaining element. Therefore, the resulting array is [1, 2].
Table of Content
[Naive Approach] Simple Simulation - O(n ^ 2) Time and O(n) Space
For every index i, calculate the XOR of all elements except arr[i]. To do this, traverse the entire array again in an inner loop and XOR every element except the current one.
#include <iostream>
#include <vector>
using namespace std;
vector<int> getXor(vector<int>& arr) {
int n = arr.size();
vector<int> res(n);
for (int i = 0; i < n; i++) {
int currXor = 0;
for (int j = 0; j < n; j++) {
if (i != j) {
currXor ^= arr[j];
}
}
res[i] = currXor;
}
return res;
}
int main() {
vector<int> arr1 = {2, 1, 5, 9};
vector<int> res1 = getXor(arr1);
for (int x : res1) {
cout << x << " ";
}
cout << endl;
vector<int> arr2 = {2, 1};
vector<int> res2 = getXor(arr2);
for (int x : res2) {
cout << x << " ";
}
return 0;
}
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static ArrayList<Integer> getXor(int[] arr) {
int n = arr.length;
ArrayList<Integer> res = new ArrayList<Integer>();
for (int i = 0; i < n; i++) {
int currXor = 0;
for (int j = 0; j < n; j++) {
if (i!= j) {
currXor ^= arr[j];
}
}
res.add(currXor);
}
return res;
}
public static void main(String[] args) {
int[] arr1 = {2, 1, 5, 9};
ArrayList<Integer> res1 = getXor(arr1);
System.out.println(res1);
int[] arr2 = {2, 1};
ArrayList<Integer> res2 = getXor(arr2);
System.out.println(res2);
}
}
def getXor(arr):
n = len(arr)
res = [0] * n
for i in range(n):
currXor = 0
for j in range(n):
if i != j:
currXor ^= arr[j]
res[i] = currXor
return res
print(getXor([2, 1, 5, 9]))
print(getXor([2, 1]))
using System;
using System.Collections.Generic;
public class Program
{
public static List<int> getXor(int[] arr)
{
int n = arr.Length;
List<int> res = new List<int>();
for (int i = 0; i < n; i++)
{
int currXor = 0;
for (int j = 0; j < n; j++)
{
if (i!= j)
{
currXor ^= arr[j];
}
}
res.Add(currXor);
}
return res;
}
public static void Main()
{
int[] arr1 = {2, 1, 5, 9};
List<int> res1 = getXor(arr1);
Console.WriteLine(string.Join(" ", res1));
int[] arr2 = {2, 1};
List<int> res2 = getXor(arr2);
Console.WriteLine(string.Join(" ", res2));
}
}
function getXor(arr) {
let n = arr.length;
let res = new Array(n);
for (let i = 0; i < n; i++) {
let currXor = 0;
for (let j = 0; j < n; j++) {
if (i !== j) {
currXor ^= arr[j];
}
}
res[i] = currXor;
}
return res;
}
console.log(getXor([2, 1, 5, 9]));
console.log(getXor([2, 1]));
Output
13 14 10 6 1 2
[Better Approach] Prefix XOR and Suffix XOR - O(n) Time and O(n) Space
Instead of recalculating the XOR for every index, precompute:
- prefixXor[i] = XOR of elements from index 0 to i
- suffixXor[i] = XOR of elements from index i to n - 1
Then for every index i: result[i] = (XOR of elements before i) XOR (XOR of elements after i). which can be obtained using prefix and suffix arrays.
#include <iostream>
#include <vector>
using namespace std;
vector<int> getXor(vector<int>& arr) {
int n = arr.size();
vector<int> prefix(n), suffix(n), res(n);
prefix[0] = arr[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] ^ arr[i];
}
suffix[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] ^ arr[i];
}
for (int i = 0; i < n; i++) {
int left = (i > 0) ? prefix[i - 1] : 0;
int right = (i < n - 1) ? suffix[i + 1] : 0;
res[i] = left ^ right;
}
return res;
}
int main() {
vector<int> arr1 = {2, 1, 5, 9};
for (int x : getXor(arr1)) {
cout << x << " ";
}
cout << endl;
vector<int> arr2 = {2, 1};
for (int x : getXor(arr2)) {
cout << x << " ";
}
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> getXor(int[] arr) {
int n = arr.length;
int[] prefix = new int[n];
int[] suffix = new int[n];
prefix[0] = arr[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] ^ arr[i];
}
suffix[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] ^ arr[i];
}
ArrayList<Integer> res = new ArrayList<>();
for (int i = 0; i < n; i++) {
int left = (i > 0) ? prefix[i - 1] : 0;
int right = (i < n - 1) ? suffix[i + 1] : 0;
res.add(left ^ right);
}
return res;
}
public static void main(String[] args) {
System.out.println(
getXor(new int[]{2, 1, 5, 9})
);
System.out.println(
getXor(new int[]{2, 1})
);
}
}
def getXor(arr):
n = len(arr)
prefix = [0] * n
suffix = [0] * n
prefix[0] = arr[0]
for i in range(1, n):
prefix[i] = prefix[i - 1] ^ arr[i]
suffix[n - 1] = arr[n - 1]
for i in range(n - 2, -1, -1):
suffix[i] = suffix[i + 1] ^ arr[i]
res = [0] * n
for i in range(n):
left = prefix[i - 1] if i > 0 else 0
right = suffix[i + 1] if i < n - 1 else 0
res[i] = left ^ right
return res
print(getXor([2, 1, 5, 9]))
print(getXor([2, 1]))
using System;
using System.Collections.Generic;
class GFG {
static List<int> getXor(int[] arr) {
int n = arr.Length;
int[] prefix = new int[n];
int[] suffix = new int[n];
prefix[0] = arr[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] ^ arr[i];
}
suffix[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] ^ arr[i];
}
List<int> res = new List<int>();
for (int i = 0; i < n; i++) {
int left = (i > 0) ? prefix[i - 1] : 0;
int right = (i < n - 1) ? suffix[i + 1] : 0;
res.Add(left ^ right);
}
return res;
}
static void Main() {
Console.WriteLine(
string.Join(" ", getXor(new int[] {2, 1, 5, 9}))
);
Console.WriteLine(
string.Join(" ", getXor(new int[] {2, 1}))
);
}
}
function getXor(arr) {
let n = arr.length;
let prefix = new Array(n);
let suffix = new Array(n);
let res = new Array(n);
prefix[0] = arr[0];
for (let i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] ^ arr[i];
}
suffix[n - 1] = arr[n - 1];
for (let i = n - 2; i >= 0; i--) {
suffix[i] = suffix[i + 1] ^ arr[i];
}
for (let i = 0; i < n; i++) {
let left = (i > 0) ? prefix[i - 1] : 0;
let right = (i < n - 1) ? suffix[i + 1] : 0;
res[i] = left ^ right;
}
return res;
}
console.log(getXor([2, 1, 5, 9]));
console.log(getXor([2, 1]));
Output
13 14 10 6 1 2
[Expected Approach] Using XOR Property - O(n) Time and O(1) Space
Observe that XOR has the following properties:
- a ^ a = 0
- a ^ 0 = a
First compute the XOR of all elements and store it in totalXor.
For any index i: totalXor = arr[0] ^ arr[1] ^ ... ^ arr[n-1], If we XOR totalXor with arr[i], arr[i] gets cancelled out. Therefore: result[i] = totalXor ^ arr[i]
#include <iostream>
#include <vector>
using namespace std;
vector<int> getXor(vector<int>& arr) {
int totalXor = 0;
for (int x : arr) {
totalXor ^= x;
}
vector<int> res(arr.size());
for (int i = 0; i < arr.size(); i++) {
res[i] = totalXor ^ arr[i];
}
return res;
}
int main() {
vector<int> arr1 = {2, 1, 5, 9};
for (int x : getXor(arr1)) {
cout << x << " ";
}
cout << endl;
vector<int> arr2 = {2, 1};
for (int x : getXor(arr2)) {
cout << x << " ";
}
return 0;
}
import java.util.ArrayList;
class GFG {
static ArrayList<Integer> getXor(int[] arr) {
int totalXor = 0;
for (int x : arr) {
totalXor ^= x;
}
ArrayList<Integer> res = new ArrayList<>();
for (int x : arr) {
res.add(totalXor ^ x);
}
return res;
}
public static void main(String[] args) {
System.out.println(
getXor(new int[] {2, 1, 5, 9})
);
System.out.println(
getXor(new int[] {2, 1})
);
}
}
def getXor(arr):
totalXor = 0
for x in arr:
totalXor ^= x
res = []
for x in arr:
res.append(totalXor ^ x)
return res
print(getXor([2, 1, 5, 9]))
print(getXor([2, 1]))
using System;
using System.Collections.Generic;
class GFG {
static List<int> getXor(int[] arr) {
int totalXor = 0;
foreach (int x in arr) {
totalXor ^= x;
}
List<int> res = new List<int>();
foreach (int x in arr) {
res.Add(totalXor ^ x);
}
return res;
}
static void Main() {
Console.WriteLine(
string.Join(" ", getXor(new int[] {2, 1, 5, 9}))
);
Console.WriteLine(
string.Join(" ", getXor(new int[] {2, 1}))
);
}
}
function getXor(arr) {
let totalXor = 0;
for (let x of arr) {
totalXor ^= x;
}
let res = [];
for (let x of arr) {
res.push(totalXor ^ x);
}
return res;
}
console.log(getXor([2, 1, 5, 9]));
console.log(getXor([2, 1]));
Output
13 14 10 6 1 2