Open In App

Minimum operations required to make every element greater than or equal to K

Last Updated : 25 Oct, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array of length N. The task is to convert it into a sequence in which all elements are greater than or equal to K.The only operation allowed is taking two smallest elements of the sequence and replace them by their LCM. Find the minimum number of operations required. 
If it is impossible to get such an array, print -1.
Examples:

Input : N = 4, K = 3 , arr=[1 4 5 5] 
Output :
LCM of 1 and 4 is 4, hence Replace (1,4) with 4. 
Now the array becomes [4,4,5]. 
Every element in this array is greater than or equal to K. 
No of operations required is equal to 1.

Input : N = 5, K = 8 , arr=[4,4,4,4,4] 
Output : -1 
It is not possible to convert the given array. 

 

Approach: 

  • The idea is to use a priority queue(min heap) which can handle delete and insert operation in log(N) time.
  • The impossible case will arise when the number of elements in the priority queue is less than 2. The answer is equal to -1 in this case.
  • Otherwise, take two elements from the top of the queue and replace it by their LCM.
  • Do this until the smallest number that is top of the queue is less than K.

Below is the implementation of above approach: 

C++




// C++ implementation of above approach
#include <bits/stdc++.h>
using namespace std;
 
// C++ function to get
// minimum operation needed
int FindMinOperation(int a[], int n, int k)
{
 
    // The priority queue holds a minimum
    // element in the top position
    priority_queue<int, vector<int>,
                              greater<int> > Q;
 
    for (int i = 0; i < n; i++)
 
        // push value one by one
        // from the given array
        Q.push(a[i]);
  
    // store count of minimum operation needed
    int ans = 0;
 
    while (1) {
 
        // All elements are now >= k
        if (Q.top() >= k)
            break;
 
        // It is impossible to make as there are
        // no sufficient elements available
        if (Q.size() < 2)
            return -1;
 
        // Take two smallest elements and
        // replace them by their LCM
        // first smallest element
        int x = Q.top();
        Q.pop();
 
        // Second smallest element
        int y = Q.top();
        Q.pop();
 
        int z = (x * y) / __gcd(x, y);
        Q.push(z);
 
        // Increment the count
        ans++;
    }
 
    return ans;
}
 
// Driver Code
int main()
{
 
    int a[] = { 3, 5, 7, 6, 8 };
    int k = 8;
    int n = sizeof(a) / sizeof(a[0]);
 
    cout << FindMinOperation(a, n, k);
}


Java




// Java implementation of above approach
import java.util.PriorityQueue;
 
class GFG
{
 
    // Function to calculate gcd of two numbers
    static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
 
    // Java function to get
    // minimum operation needed
    static int FindMinOperation(int[] a, int n, int k)
    {
 
        // The priority queue holds a minimum
        // element in the top position
        PriorityQueue<Integer> Q = new PriorityQueue<>();
 
        for (int i = 0; i < n; i++)
 
            // push value one by one
            // from the given array
            Q.add(a[i]);
 
        // store count of minimum operation needed
        int ans = 0;
 
        while (true)
        {
 
            // All elements are now >= k
            if (Q.peek() >= k)
                break;
 
            // It is impossible to make as there are
            // no sufficient elements available
            if (Q.size() < 2)
                return -1;
 
            // Take two smallest elements and
            // replace them by their LCM
            // first smallest element
            int x = Q.peek();
            Q.poll();
 
            // Second smallest element
            int y = Q.peek();
            Q.poll();
 
            int z = (x * y) / gcd(x, y);
            Q.add(z);
 
            // Increment the count
            ans++;
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] a = { 3, 5, 7, 6, 8 };
        int k = 8;
        int n = a.length;
        System.out.println(FindMinOperation(a, n, k));
    }
}
 
// This code is contributed by
// sanjeev2552


Python3




# Python3 implementation of above approach
 
# Function to calculate gcd of two numbers
def gcd(a, b) :
 
    if (a == 0) :
      return b
    return gcd(b % a, a)
     
# function to get 
# minimum operation needed
def FindMinOperation(a, n, k) :
     
    # The priority queue holds a minimum
    # element in the top position
    Q = []
    for i in range(0, n) :
     
      # push value one by one
      # from the given array
      Q.append(a[i])
    Q.sort()
     
    # store count of minimum operation needed
    ans = 0
    while (True) :
     
      # All elements are now >= k
      if (Q[0] >= k) :
        break
     
      # It is impossible to make as there are
      # no sufficient elements available
      if (len(Q) < 2) :
        return -1
     
      # Take two smallest elements and 
      # replace them by their LCM
      # first smallest element
      x = Q[0
      Q.pop(0)
     
      # Second smallest element
      y = Q[0
      Q.pop(0)
      z = (x * y) // gcd(x, y)
      Q.append(z)
      Q.sort()
     
      # Increment the count
      ans += 1 
  
    return ans
     
  # Driver code
a = [ 3, 5, 7, 6, 8 ]
k = 8
n = len(a)
 
print(FindMinOperation(a, n, k))
 
# This code is contributed by divyesh0720219.


C#




// C# implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to calculate gcd of two numbers
  static int gcd(int a, int b)
  {
    if (a == 0)
      return b;
    return gcd(b % a, a);
  }
 
  // C# function to get 
  // minimum operation needed
  static int FindMinOperation(int[] a, int n, int k)
  {
 
    // The priority queue holds a minimum
    // element in the top position
    List<int> Q = new List<int>();
    for (int i = 0; i < n; i++)
 
      // push value one by one
      // from the given array
      Q.Add(a[i]);
    Q.Sort();
 
    // store count of minimum operation needed
    int ans = 0; 
    while (true)
    {
 
      // All elements are now >= k
      if (Q[0] >= k)
        break;
 
      // It is impossible to make as there are
      // no sufficient elements available
      if (Q.Count < 2)
        return -1;
 
      // Take two smallest elements and 
      // replace them by their LCM
      // first smallest element
      int x = Q[0]; 
      Q.RemoveAt(0);
 
      // Second smallest element
      int y = Q[0]; 
      Q.RemoveAt(0);
      int z = (x * y) / gcd(x, y);
      Q.Add(z);
      Q.Sort();
 
      // Increment the count
      ans++; 
    }
    return ans;
  }
 
  // Driver code
  static void Main()
  {
    int[] a = { 3, 5, 7, 6, 8 };
    int k = 8;
    int n = a.Length;
 
    Console.WriteLine(FindMinOperation(a, n, k));
  }
}
 
// This code is contributed by divyeshrabadiya07.


Javascript




<script>
    // Javascript implementation of above approach
       
    // Function to calculate gcd of two numbers
    function gcd(a, b)
    {
      if (a == 0)
        return b;
      return gcd(b % a, a);
    }
 
    // function to get
    // minimum operation needed
    function FindMinOperation(a, n, k)
    {
 
      // The priority queue holds a minimum
      // element in the top position
      let Q = [];
      for (let i = 0; i < n; i++)
 
        // push value one by one
        // from the given array
        Q.push(a[i]);
      Q.sort(function(a, b){return a - b});
 
      // store count of minimum operation needed
      let ans = 0;
      while (true)
      {
 
        // All elements are now >= k
        if (Q[0] >= k)
          break;
 
        // It is impossible to make as there are
        // no sufficient elements available
        if (Q.length < 2)
          return -1;
 
        // Take two smallest elements and
        // replace them by their LCM
        // first smallest element
        let x = Q[0];
        Q.shift();
 
        // Second smallest element
        let y = Q[0];
        Q.shift();
        let z = parseInt((x * y) / gcd(x, y), 10);
        Q.push(z);
        Q.sort(function(a, b){return a - b});
 
        // Increment the count
        ans++;
      }
      return ans;
    }
       
    let a = [ 3, 5, 7, 6, 8 ];
    let k = 8;
    let n = a.length;
  
    document.write(FindMinOperation(a, n, k));
     
</script>


Output

2

Time Complexity: O(NlogN)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads