Open In App

Compute AND value by doing XOR of given arrays

Improve
Improve
Like Article
Like
Save
Share
Report

Given two arrays A[] and B[], the array C[] is formed by the XOR of ai and bi, i.e ci = ai^bi, the task is to find the maximum AND value of all the array elements of C given that A and B can be permuted in any way.

Examples:

Input: A[] ={1, 0, 0, 3, 3}, B[] =  {2, 3, 2, 1, 0}
Output: 2
Explanation:  C [] = {3, 3, 2, 2, 3}  on doing AND of array C value of AND is (3 & 3 & 2 & 2 & 3) = 2 which is the maximum possible AND value considering any permutations of A and B arrays.

Input: A[] = {1, 1, 1}, B[] = {0, 0, 3}
Output:
Explanation: C[] = {1, 1, 2} on doing AND of array C value of AND is (1&1&2) = 0 which is the maximum possible AND value considering any permutations of A and B arrays.

Approach: To solve the problem follow the below idea:

The approach is Greedy where we check from setting the bit from the MSB in the result would result in any permutation of A and B such that, that bit is set in all elements of  C i.e C[i] = A[i] ^ B[i] is set or A[i] & ~B[i], to make bit set in result which is the final AND all the Ci should have that set bit so we check if there is a possibility to have that ith bit set if it is possible we set that bit in the result else not.
The main point is A and B should have matched opposite values so that A[i] ^ B[i] is 1 if A[i] as the kth bit set then there should be a number in B where kth bit is unset.

Follow these steps to solve the above problem:

  • Define a function check that takes in an integer res and the two arrays A and B along with their size n. This function will return a boolean value indicating whether it is possible to set the ith bit in res.
  • Inside the function, define two vectors v1 and v2. These vectors will store the results of the AND operation between res and each element of A, and between res and the negation of each element of B, respectively.
  • Populate the vectors v1 and v2 with the results of the AND operation between res and each element of A, and between res and the negation of each element of B, respectively.
  • Sort the vectors v1 and v2 in ascending order.
  • Iterate over the elements of v1 and v2 and compare them. If any pair of elements from the same indices in v1 and v2 are not equal, return false. Otherwise, return true.
  • Define a function find_max_and that takes in the arrays A and B and their size n. This function will return the maximum number that can be obtained by performing the bitwise AND operation on all possible pairs of elements from A and B.
  • Inside the function, initialize a variable res to 0.
  • Iterate from the most significant bit (29) to the least significant bit (0), decrementing the loop variable i by 1 on each iteration.
  • On each iteration, call the function to check if it is possible to form any permutations of A[] and B[] such that the ith bit is set.
  • Return res.

Below is the implementation of the above approach:

C++




// C++ code for the above approach
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
 
// Function to check if it is possible to
// obtain 'res' by performing the AND
// operation on all possible pairs of
// elements from 'A' and 'B'
bool check(ll res, ll A[], ll B[], ll n)
{
 
    // Vectors to store the results of the
    // AND operation between 'res' and
    // each element of 'A', and between
    // 'res' and the negation of each
    // element of 'B', respectively
    vector<ll> v1, v2;
 
    // Populate vectors v1 and v2
    for (ll i = 0; i < n; i++) {
        v1.push_back(res & A[i]);
        v2.push_back(res & ~B[i]);
    }
 
    // Sort v1 and v2 in ascending order
    sort(v1.begin(), v1.end());
    sort(v2.begin(), v2.end());
 
    // Check if there are equal number
    // of 0, 1 pairs
    for (ll i = 0; i < n; i++) {
 
        // If any pair of elements from
        // the same indices in v1 and v2
        // are not equal, return false
        if (v1[i] != v2[i]) {
            return false;
        }
    }
 
    // If all pairs of elements from
    // v1 and v2 are equal, return true
    return true;
}
 
// Function to find the maximum AND value
ll find_max_and(ll A[], ll B[], ll n)
{
 
    // Initialize 'res' to 0
    ll res = 0;
 
    // Iterate from the most significant
    // bit (29) to the least
    // significant bit (0)
    for (ll i = 29; i >= 0; i--) {
 
        // Check if it is possible to
        // obtain any permutations of A
        // and B such that ith bit is set
        // in all the elements of C[i]
        if (check(res | (1 << i), A, B, n)) {
 
            // Set the ith bit in the res
            res = (res | (1 << i));
        }
    }
    return res;
}
 
// Driver Code
int main()
{
 
    // Arrays A and B
    ll A[] = { 1, 0, 0, 3, 3 };
    ll B[] = { 2, 3, 2, 1, 0 };
 
    // Size of A and B
    ll n = sizeof(A) / sizeof(A[0]);
 
    // Print 'res'
    cout << find_max_and(A, B, n) << "\n";
 
    ll A2[] = { 1, 1, 1 };
    ll B2[] = { 0, 0, 3 };
 
    // Size of A and B
    ll n2 = sizeof(A2) / sizeof(A2[0]);
 
    // Print 'res'
    cout << find_max_and(A2, B2, n2) << "\n";
 
    return 0;
}


Java




// Java code for the above approach
import java.util.*;
 
public class Main {
 
    // Function to check if it is possible to obtain 'res' by performing
    // the AND operation on all possible pairs of elements from 'A' and 'B'
    static boolean check(long res, long[] A, long[] B, long n) {
 
        // Lists to store the results of the AND operation between 'res' and
        // each element of 'A', and between 'res' and the negation of each
        // element of 'B', respectively
        List<Long> v1 = new ArrayList<>();
        List<Long> v2 = new ArrayList<>();
 
        // Populate lists v1 and v2
        for (long i = 0; i < n; i++) {
            v1.add(res & A[(int) i]);
            v2.add(res & ~B[(int) i]);
        }
 
        // Sort v1 and v2 in ascending order
        Collections.sort(v1);
        Collections.sort(v2);
 
        // Check if there are equal number of 0, 1 pairs
        for (long i = 0; i < n; i++) {
 
            // If any pair of elements from the same indices in v1 and v2
            // are not equal, return false
            if (!Objects.equals(v1.get((int) i), v2.get((int) i))) {
                return false;
            }
        }
 
        // If all pairs of elements from v1 and v2 are equal, return true
        return true;
    }
 
    // Function to find the maximum AND value
    static long findMaxAnd(long[] A, long[] B, long n) {
 
        // Initialize 'res' to 0
        long res = 0;
 
        // Iterate from the most significant bit (29) to the least
        // significant bit (0)
        for (long i = 29; i >= 0; i--) {
 
            // Check if it is possible to obtain any permutations of A
            // and B such that ith bit is set in all the elements of C[i]
            if (check(res | (1 << i), A, B, n)) {
 
                // Set the ith bit in the res
                res = res | (1 << i);
            }
        }
        return res;
    }
 
    public static void main(String[] args) {
 
        // Arrays A and B
        long[] A = {1, 0, 0, 3, 3};
        long[] B = {2, 3, 2, 1, 0};
 
        // Size of A and B
        long n = A.length;
 
        // Print 'res'
        System.out.println(findMaxAnd(A, B, n));
 
        long[] A2 = {1, 1, 1};
        long[] B2 = {0, 0, 3};
 
        // Size of A and B
        long n2 = A2.length;
 
        // Print 'res'
        System.out.println(findMaxAnd(A2, B2, n2));
    }
}


Python3




# Python code for the equivalent approach
 
# Function to check if it is possible to
# obtain 'res' by performing the AND
# operation on all possible pairs of
# elements from 'A' and 'B'
def check(res, A, B, n):
      # Vectors to store the results of the
    # AND operation between 'res' and
    # each element of 'A', and between
    # 'res' and the negation of each
    # element of 'B', respectively
    v1, v2 = [], []
     
    # Populate vectors v1 and v2
    for i in range(n):
        v1.append(res & A[i])
        v2.append(res & (~B[i]))
         
    # Sort v1 and v2 in ascending order
    v1.sort()
    v2.sort()
     
    # Check if there are equal number
    # of 0, 1 pairs
    for i in range(n):
       
          # If any pair of elements from
        # the same indices in v1 and v2
        # are not equal, return false
        if v1[i] != v2[i]:
            return False
    # If all pairs of elements from
    # v1 and v2 are equal, return true
    return True
 
# Function to find the maximum AND value
def find_max_and(A, B, n):
      # Initialize 'res' to 0
    res = 0
     
    # Iterate from the most significant
    # bit (29) to the least
    # significant bit (0)
    for i in range(29, -1, -1):
       
          # Check if it is possible to
        # obtain any permutations of A
        # and B such that ith bit is set
        # in all the elements of C[i]
        if check(res | (1 << i), A, B, n):
               
            # Set the ith bit in the res
            res = res | (1 << i)
    return res
 
 
# Arrays A and B
A = [1, 0, 0, 3, 3]
B = [2, 3, 2, 1, 0]
 
# Size of A and B
n = len(A)
 
# Print 'res'
print(find_max_and(A, B, n))
 
A2 = [1, 1, 1]
B2 = [0, 0, 3]
 
# Size of A and B
n2 = len(A2)
 
# Print 'res'
print(find_max_and(A2, B2, n2))
 
# This code is contributed by lokeshmvs21.


Javascript




// Javascript code for the above approach
 
// Function to check if it is possible to
// obtain 'res' by performing the AND
// operation on all possible pairs of
// elements from 'A' and 'B'
function check(res, A, B, n)
{
 
    // Vectors to store the results of the
    // AND operation between 'res' and
    // each element of 'A', and between
    // 'res' and the negation of each
    // element of 'B', respectively
    let v1=new Array(), v2=new Array();
 
    // Populate vectors v1 and v2
    for (let i = 0; i < n; i++) {
        v1.push(res & A[i]);
        v2.push(res & ~B[i]);
    }
 
    // Sort v1 and v2 in ascending order
    v1.sort();
    v2.sort();
 
    // Check if there are equal number
    // of 0, 1 pairs
    for (let i = 0; i < n; i++) {
 
        // If any pair of elements from
        // the same indices in v1 and v2
        // are not equal, return false
        if (v1[i] != v2[i]) {
            return false;
        }
    }
 
    // If all pairs of elements from
    // v1 and v2 are equal, return true
    return true;
}
 
// Function to find the maximum AND value
function find_max_and( A,  B,  n)
{
 
    // Initialize 'res' to 0
    let res = 0;
 
    // Iterate from the most significant
    // bit (29) to the least
    // significant bit (0)
    for (let i = 29; i >= 0; i--) {
 
        // Check if it is possible to
        // obtain any permutations of A
        // and B such that ith bit is set
        // in all the elements of C[i]
        if (check(res | (1 << i), A, B, n)) {
 
            // Set the ith bit in the res
            res = (res | (1 << i));
        }
    }
    return res;
}
 
// Driver Code
// Arrays A and B
let A =[ 1, 0, 0, 3, 3 ];
let B =[ 2, 3, 2, 1, 0 ];
 
// Size of A and B
let n = A.length;
 
// Print 'res'
console.log(find_max_and(A, B, n));
 
let A2 = [ 1, 1, 1 ];
let B2 = [ 0, 0, 3 ];
 
// Size of A and B
let n2 = A2.length;
 
// Print 'res'
console.log(find_max_and(A2, B2, n2));


C#




// C# code for the above approach
using System;
using System.Collections.Generic;
 
class MainClass {
    // Function to check if it is possible to
    // obtain 'res' by performing the AND
    // operation on all possible pairs of
    // elements from 'A' and 'B'
    static bool check(int res, int[] A, int[] B, int n) {
        // Vectors to store the results of the
        // AND operation between 'res' and
        // each element of 'A', and between
        // 'res' and the negation of each
        // element of 'B', respectively
        List<int> v1 = new List<int>();
        List<int> v2 = new List<int>();
 
        // Populate vectors v1 and v2
        for (int i = 0; i < n; i++) {
            v1.Add(res & A[i]);
            v2.Add(res & (~B[i]));
        }
 
        // Sort v1 and v2 in ascending order
        v1.Sort();
        v2.Sort();
 
        // Check if there are equal number
        // of 0, 1 pairs
        for (int i = 0; i < n; i++) {
 
            // If any pair of elements from
            // the same indices in v1 and v2
            // are not equal, return false
            if (v1[i] != v2[i]) {
                return false;
            }
        }
        // If all pairs of elements from
        // v1 and v2 are equal, return true
        return true;
    }
 
    // Function to find the maximum AND value
    static int find_max_and(int[] A, int[] B, int n) {
        // Initialize 'res' to 0
        int res = 0;
 
        // Iterate from the most significant
        // bit (29) to the least
        // significant bit (0)
        for (int i = 29; i >= 0; i--) {
 
            // Check if it is possible to
            // obtain any permutations of A
            // and B such that ith bit is set
            // in all the elements of C[i]
            if (check(res | (1 << i), A, B, n)) {
 
                // Set the ith bit in the res
                res = res | (1 << i);
            }
        }
        return res;
    }
 
    public static void Main() {
        // Arrays A and B
        int[] A = { 1, 0, 0, 3, 3 };
        int[] B = { 2, 3, 2, 1, 0 };
 
        // Size of A and B
        int n = A.Length;
 
        // Print 'res'
        Console.WriteLine(find_max_and(A, B, n));
 
        int[] A2 = { 1, 1, 1 };
        int[] B2 = { 0, 0, 3 };
 
        // Size of A and B
        int n2 = A2.Length;
 
        // Print 'res'
        Console.WriteLine(find_max_and(A2, B2, n2));
    }
}
// This code is contributed by shivamsharma215.


Output

2
0

Time Complexity: O(NlogN), where N is the size of the array
Auxiliary Space: O(N)

Related Articles:



Last Updated : 23 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads