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 : 1
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 |
2
Time Complexity: O(NlogN)
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.