Maximize XOR subsequence possible by equidistant elements from both ends

Given an array A[] of size N, find the Maximum Xor Subsequence such that both A [ i ] and A [ N – i – 1 ] belong to this subsequence, where i ranges between [0, N – 1].

Examples:

Input: N = 8, A [ ] = {1, 2, 3, 4, 5, 6, 7, 8}
Output: 13
Explanation:
Maximum Xor Subsequence is {1, 3, 4, 5, 6, 8}

Input: N = 5, A [ ] = {3, 2, 6, 5, 4}
Output: 6
Explanation:
Maximum Xor Subsequence is {3, 2, 6, 5, 4}

Approach:
Since, both A[i] and A[N-i-1] should be present in the same subsequence, pair them up and then find maximum xor sum. For each valid index i, calculate (A[i] ^ A[N-i-1]) and store it in new array X. Size of this new array will be N/2.



Naive Solution:
The simplest approach after creating array X[] for this problem is to recursively generate all subsequences of X and find the maximum xor subsequence.
Following is the recursive definition of maxXorSubseq(X, N, i):

maxXorSubseq ( X, N, i ) = MAX ( X[ i ] ^ maxXorSubseq ( X, N, i + 1 ), maxXorSubseq (X, N, i + 1) )

The total possible combinations will be 2N.
Time Complexity: O(2N)

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation
// of the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Returns maximum xor
int maxXorSubseq(vector<int> &x, int n,
                                 int i)
{
    if(i == n)
       return 0;
  
    return max(x[i] ^ maxXorSubseq(x, n, 
                                   i + 1), 
                      maxXorSubseq(x, n, 
                                   i + 1));
}
  
vector<int> compute(vector<int> a, int n)
{
    vector<int> x;
  
    // Calculate a[i]^a[n-i-1]
    for(int i = 0; i < n / 2; i++)
       x.push_back(a[i] ^ a[n - i - 1]);
  
    // If n is odd
    if(n & 1)
       x.push_back(a[n / 2]);
  
    return x;
}
  
// Driver code
int main()
{
    int n = 8;
    vector<int> a = { 1, 2, 3, 4,
                      5, 6, 7, 8 };
      
    // Getting new array x
    vector<int> x = compute(a, n);
      
    int mxXor = maxXorSubseq(x, x.size(), 0);
      
    cout << (mxXor);
    return 0;
}
  
// This code is contributed by mohit kumar 29    

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation 
// of the above approach 
import java.util.*;
  
class GFG{
  
// Returns maximum xor
static int maxXorSubseq(List<Integer> x, int n,
                                         int i)
{
    if(i == n)
    return 0;
  
    return Math.max(x.get(i) ^ maxXorSubseq(x, n, 
                                            i + 1), 
                               maxXorSubseq(x, n, 
                                            i + 1));
}
  
static List<Integer> compute(List<Integer> a, int n)
{
    List<Integer> x = new ArrayList<Integer>();
  
    // Calculate a[i]^a[n-i-1]
    for(int i = 0; i < n / 2; i++)
        x.add(a.get(i) ^ a.get(n - i - 1));
  
    // If n is odd
    if((n & 1) == 1)
        x.add(a.get(n / 2));
  
    return x;
}
  
// Driver code
public static void main(String[] args)
{
    int n = 8;
    List<Integer> a = Arrays.asList( 1, 2, 3, 4,
                                     5, 6, 7, 8 );
      
    // Getting new array x
    List<Integer> x = compute(a, n);
      
    int mxXor = maxXorSubseq(x, x.size(), 0);
      
    System.out.println((mxXor));
}
}
  
// This code is contributed by offbeat

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation
# of the above approach
  
# Returns maximum xor 
def maxXorSubseq(x, n, i):
      
    if(i == n):
        return 0
          
    return max(
        x[i]^maxXorSubseq(
        x, n, i + 1), maxXorSubseq(
        x, n, i + 1))
  
def compute(a, n):
      
    x = []
      
    # Calculate a[i]^a[n-i-1]
    for i in range(n//2):     
        x.append(a[i]^a[n-i-1])
      
    # If n is odd
    if(n&1):
        x.append(a[n//2])
          
    return x
  
# Driver code
if __name__ =="__main__":
      
    n = 8
    a = [1, 2, 3, 4, 5, 6, 7, 8]
      
    # Getting new array x
    x = compute(a, n)
      
    mxXor = maxXorSubseq(x, len(x), 0)
      
    print(mxXor)

chevron_right


Output:

13

Efficient Approach:
Considering the above implementation, the following is a partial recursion tree for input X = [9, 5, 1]

In the above partial recursion tree, maxXorSubseq({1}) is being solved four times. On drawing the complete recursion tree, it can be observed that there are many subproblems that are solved again and again. So this problem has Overlapping Subproblems and recomputation of the same subproblems can be avoided by using Memoization.

For memoization, create an array dp [ ] array and store:

dp[i] = max(x[i] ^ maxXorSubseq(x, n, i + 1), maxXorSubseq(x, n, idx + 1)

This avoids recalculation for previously calculated indices thus optimizing computational complexity.

Below is the implementation of the above approach:

Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation
# of the above approach
  
# Returns maximum xor sum
def maxXorSubseq(x, n, idx):
      
    if(idx == n):
        return 0
          
    # If already precomputed
    if(dp[idx]!=-1):
        return dp[idx]
  
    ans = 0
      
    ans = max(
        ans, x[idx] ^ maxXorSubseq(
                    x, n, idx + 1))
      
    ans = max(ans, maxXorSubseq(
                    x, n, idx + 1))
      
    # Store the maximum
    dp[idx] = ans
      
    return ans
  
def compute(a, n):
      
    x = []
      
    # Calculate a[i]^a[n-i-1]
    for i in range(n//2): 
        x.append(a[i]^a[n-i-1])
      
    # If n is odd
    if(n&1):
        x.append(a[n//2])
          
    return x
      
# Declared dp[] array globally
dp = []
  
# Driver code
if __name__ =="__main__":
      
    n = 8
    a =[1, 2, 3, 4, 5, 6, 7, 8]
      
    # Getting new array x
    x = compute(a, n)
  
    # Initialize dp array
    dp = [-1 for i in range(len(x))]
      
    mxXor = maxXorSubseq(x, len(x), 0)
      
    print(mxXor)
     

chevron_right


Output:

13

Time complexity: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : mohit kumar 29, offbeat