Open In App

Minimum operations required to make two elements equal in Array

Last Updated : 24 Feb, 2023
Comments
Improve
Suggest changes
Like Article
Like
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:


Next Article

Similar Reads