Open In App

Minimum operations required to make two elements equal in Array

Improve
Improve
Like Article
Like
Save
Share
Report

Given array A[] of size N and integer X, the task is to find the minimum number of operations to make any two elements equal in the array. In one operation choose any element A[i] and replace it with A[i] & X. where & is bitwise AND. If such operations do not exist print -1.

Examples: 

Input: A[] = {1, 2, 3, 7}, X = 3
Output: 1
Explanation: Performing above operation on A[4] = 7, A[4] = A[4] & X  = 7 & 3 = 3. Array A[] becomes {1, 2, 3, 3}, 3 exists on 3rd position so in one operation two elements can be made equal in array A[].

Input: A[] = {1, 2, 3}, X = 7
Output: -1
Explanation: It is not possible to make any two elements equal by performing above operations any number of times.

Naive approach: The basic way to solve the problem is as follows:

Making bitwise AND of current element and checking whether if any other element exists with same value.

Time Complexity: O(N2)
Auxiliary Space: O(1)

Efficient Approach:  The above approach can be optimized based on the following idea:

This problem can be divided in four cases:

  • Case 1: Two equal elements already exist in array A[], In that case answer will be 0.
  • Case 2: It is not possible to create two elements which are equal by above operations, In that case answer will be -1.
  • Case 3: It is possible to make any two elements equal by performing above operations exactly once.
  • Case 4: It is possible to make any two elements equal by performing above operations exactly twice.

Follow the steps below to solve the problem:

  • Creating HashMap[].
  • Iterating from 1 to N and filling frequency HashMap[] if some element repeats again return 0.
  • Iterating from 1 to N and for each iteration remove the current element from HashMap[] and perform an operation on the current index and check whether it exists in HashMap[] if it exists return 1 else insert the current element again in HashMap[].
  • Clear the HashMap[].
  • Iterating from 1 to N and performing an operation on each element along with filling HashMap[], if the frequency of any element is more than 2 then return 2.
  • Finally, if the function reaches the end return -1.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to minimum operations required
// to make two elements equal in array.
int minOperations(int A[], int N, int M)
{
 
    // Creating HashMap
    map<int, int> HashMap;
 
    for (int i = 0; i < N; i++) {
 
        // Filling frequency HashMap
        HashMap[A[i]]++;
 
        // If two values same already exist
        if (HashMap[A[i]] >= 2)
            return 0;
    }
 
    for (int i = 0; i < N; i++) {
 
        // Removing occurrence of current
        // element from HashMap
        HashMap[A[i]]--;
 
        // Performing operation on
        // current index
        int performOperation = A[i] & M;
 
        // Check if another element exists
        // with same value
        if (HashMap[performOperation])
            return 1;
 
        // Inserting back occurrence
        // of element
        HashMap[A[i]]++;
    }
 
    // Clearing the HashMap
    HashMap.clear();
 
    for (int i = 0; i < N; i++) {
 
        // Performing operation on
        // current index
        int performOperation = A[i] & M;
 
        // Inserting this element
        // in Hashmap
        HashMap[performOperation]++;
 
        // If two elements exist such that
        // both formed with operation
        if (HashMap[A[i]] == 2)
            return 2;
    }
 
    // If answer do not exist
    return -1;
}
 
// Driver Code
int main()
{
 
    // Input 1
    int A[] = { 1, 2, 3, 7 };
    int N = sizeof(A) / sizeof(A[0]);
    int X = 3;
 
    // Function Call
    cout << minOperations(A, N, X) << endl;
 
    // Input 2
    int A1[] = { 1, 2, 3 };
    int N1 = sizeof(A1) / sizeof(A1[0]);
    int X1 = 7;
 
    // Function Call
    cout << minOperations(A1, N1, X1) << endl;
    return 0;
}


Python3




# Python code to implement the approach
 
# Function to minimum operations required
# to make two elements equal in array.
def minOperations(A, N, M):
    # Creating HashMap
    HashMap = {}
     
    for i in range(N):
        # If two values same already exist
        if A[i] in HashMap: return 0
        # Filling frequency HashMap
        else: HashMap[A[i]] = 1
     
    for i in range(N):
        # Removing occurrence of current
        # element from HashMap
        HashMap[A[i]] -= 1
         
        # Performing operation on
        # current index
        performOperation = A[i] & M
 
        # Check if another element exists
        # with same value
        if (HashMap[performOperation]): return 1
 
        # Inserting back occurrence
        # of element
        HashMap[A[i]] += 1
 
    # Clearing the HashMap
    HashMap = {}
    for i in range(N):
        # Performing operation on
        # current index
        performOperation = A[i] & M
 
        # Inserting this element
        # in Hashmap
        if performOperation in HashMap: HashMap[performOperation] += 1
        else: HashMap[performOperation] = 1
 
        # If two elements exist such that
        # both formed with operation
        if (HashMap[A[i]] == 2): return 2
 
    # If answer do not exist
    return -1
     
# Driver Code
 
# Input 1
A = [1, 2, 3, 7]
N = len(A)
X = 3
# Function Call
print(minOperations(A, N, X))
 
# Input 2
A1 = [1, 2, 3]
N1 = len(A1)
X1 = 7
# Function Call
print(minOperations(A1, N1, X1))


C#




//C# code to implement the approach
using System;
using System.Collections.Generic;
 
// Function to minimum operations required
// to make two elements equal in array.
class MainClass {
            
        public static int MinOperations(int[] A, int N, int M) {
        // Creating HashMap
        Dictionary<int, int> HashMap = new Dictionary<int, int>();
 
        for (int i = 0; i < N; i++)
        {
            // Filling frequency HashMap
            if (HashMap.ContainsKey(A[i]))
            {
                HashMap[A[i]]++;
            } else {
                HashMap.Add(A[i], 1);
            }
 
            // If two values same already exist
            if (HashMap[A[i]] >= 2)
            {
                return 0;
            }
        }
 
        for (int i = 0; i < N; i++)
        {
            // Removing occurrence of current element from HashMap
            HashMap[A[i]]--;
 
            // Performing operation on current index
            int performOperation = A[i] & M;
 
            // Check if another element exists with same value
            if (HashMap.ContainsKey(performOperation) &&
                HashMap[performOperation] > 0) {
                return 1;
            }
 
            // Inserting back occurrence of element
            HashMap[A[i]]++;
        }
 
        // Clearing the HashMap
        HashMap.Clear();
 
        for (int i = 0; i < N; i++)
        {
            // Performing operation on current index
            int performOperation = A[i] & M;
 
            // Inserting this element in Hashmap
            if (HashMap.ContainsKey(performOperation))
            {
                HashMap[performOperation]++;
            }
            else
            {
                HashMap.Add(performOperation, 1);
            }
 
            // If two elements exist such that both formed with operation
            if (HashMap[performOperation] == 2)
            {
                return 2;
            }
        }
 
        // If answer do not exist it will return -1
        return -1;
    }
     
   // Drive Code
    public static void Main(string[] args)
    {
        // Input 1
        int[] A = { 1, 2, 3, 7 };
        int N = A.Length;
        int X = 3;
 
        // Test Case 1 Function Call
         Console.WriteLine(MinOperations(A, N, X));
 
        // Input 2
         int[] A1 = { 1, 2, 3 };
         int N1 = A1.Length;
         int X1 = 7;
 
        // Test Case 2 Function Call
        Console.WriteLine(MinOperations(A1, N1, X1));
    }
}
 
// This Code is contributed by nikhilsainiofficial546


Javascript




// JavaScript code to implement the approach
function minOperations(A, N, M) {
  // Creating HashMap
  let HashMap = {};
 
  for (let i = 0; i < N; i++) {
    // Filling frequency HashMap
    if (HashMap[A[i]] === undefined) HashMap[A[i]] = 0;
    HashMap[A[i]]++;
 
    // If two values same already exist
    if (HashMap[A[i]] >= 2) return 0;
  }
 
  for (let i = 0; i < N; i++) {
    // Removing occurrence of current
    // element from HashMap
    HashMap[A[i]]--;
 
    // Performing operation on
    // current index
    let performOperation = A[i] & M;
 
    // Check if another element exists
    // with same value
    if (HashMap[performOperation]) return 1;
 
    // Inserting back occurrence
    // of element
    HashMap[A[i]]++;
  }
 
  // Clearing the HashMap
  HashMap = {};
 
  for (let i = 0; i < N; i++) {
    // Performing operation on
    // current index
    let performOperation = A[i] & M;
 
    // Inserting this element
    // in Hashmap
    if (HashMap[performOperation] === undefined) HashMap[performOperation] = 0;
    HashMap[performOperation]++;
 
    // If two elements exist such that
    // both formed with operation
    if (HashMap[A[i]] === 2) return 2;
  }
 
  // If answer do not exist
  return -1;
}
 
// Input 1
let A = [1, 2, 3, 7];
let N = A.length;
let X = 3;
 
// Function Call
console.log(minOperations(A, N, X));
 
// Input 2
let A1 = [1, 2, 3];
let N1 = A1.length;
let X1 = 7;
 
// Function Call
console.log(minOperations(A1, N1, X1));


Java




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
  
class GFG {
    // Function to minimum operations required
    // to make two elements equal in array.
    static int minOperations(int A[], int N, int M)
    {
     
        // Creating HashMap
        Map<Integer, Integer> HashMap = new HashMap<Integer, Integer>();
 
     
        for (int i = 0; i < N; i++)
        {
     
            // Filling frequency HashMap
            if (HashMap.containsKey(A[i]))
                HashMap.put(A[i], HashMap.get(A[i]) + 1);
            else
                HashMap.put(A[i], 1);
 
            // If two values same already exist
            if (HashMap.get(A[i]) >= 2)
                return 0;
        }
     
        for (int i = 0; i < N; i++) {
     
            // Removing occurrence of current
            // element from HashMap
            if (HashMap.containsKey(A[i]))
                HashMap.put(A[i], HashMap.get(A[i]) - 1);
            else
                HashMap.put(A[i], 1);
     
            // Performing operation on
            // current index
            int performOperation = A[i] & M;
     
            // Check if another element exists
            // with same value
            if (HashMap.get(performOperation)>0)
                return 1;
     
            // Inserting back occurrence
            // of element
            if (HashMap.containsKey(A[i]))
                HashMap.put(A[i], HashMap.get(A[i]) + 1);
            else
                HashMap.put(A[i], 1);
        }
     
        // Clearing the HashMap
        HashMap.clear();
     
        for (int i = 0; i < N; i++) {
     
            // Performing operation on
            // current index
            int performOperation = A[i] & M;
     
            // Inserting this element
            // in Hashmap
            if (HashMap.containsKey(A[i]))
                HashMap.put(A[i], HashMap.get(A[i]) + 1);
            else
                HashMap.put(A[i], 1);
     
            // If two elements exist such that
            // both formed with operation
            if (HashMap.get(A[i]) == 2)
                return 2;
        }
     
        // If answer do not exist
        return -1;
    }
     
    // Driver Code
    public static void main(String args[])
    {
     
        // Input 1
        int A[] = { 1, 2, 3, 7 };
        int N = A.length;
        int X = 3;
     
        // Function Call
        System.out.println(minOperations(A, N, X));
     
        // Input 2
        int A1[] = { 1, 2, 3 };
        int N1 = A1.length;
        int X1 = 7;
     
        // Function Call
        System.out.println(minOperations(A1, N1, X1));
    }
}


Output

1
-1

Time Complexity: O(N*logN)  
Auxiliary Space: O(N)

Related Articles:



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