Given an array arr[] and an integer K. The following operations can be performed on any array element:
- Multiply the array element with K.
- If the element is divisible by K, then divide it by K.
The above two operations can be applied any number of times including zero on any array element. The task is to find the minimum difference possible between the maximum and minimum value of the array.
Examples:
Input: arr[] = {1, 5000, 9999}, K = 10000
Output: 5000
Explanation:
The minimum possible difference between maximum element and minimum element is 5000. When element 1 is multiplied by K, the maximum element of the array becomes 10000 and minimum element is 5000. And, this is the least possible value.
Input: arr[] = {1, 2, 3, 4, 5, 10, 7}, K = 5
Output: 5
Explanation:
In the first step, the elements 5 and 10 can be divided with 5 making it 1 and 2 respectively.
In the second step, 1 can be multiplied by 5. This makes 2 the minimum element and 7 the maximum element in the array. Therefore, the difference is 5.
Approach: The idea is to use Priority Queue as a Multiset. The following steps can be followed to compute the answer:
- Initially, all the possible values (i.e.) the value obtained when the array element is multiplied by K, divided by K are inserted in the multiset along with the indices.
- Continuously pop-out values from the multiset. At each instance, the popped-out value X with index i is the maximum and if at least one value has been popped out for all indices, the current answer will be X – min of (max of previously popped-out values for an index) for all indices except i.
- Update the answer if the current difference is less then what is calculated till now.
- This is continued till there are elements left in the multiset.
Below is the implementation of the above approach:
C++
// C++ implementation of the above approach #include<bits/stdc++.h> using namespace std; // Function to calculate Minimum // difference between maximum and // minimum value of the array int calculateMinDiff( int arr[], int k , int n) { // Variable to store minimum difference int ans = INT_MAX; // PriorityQueue which is used as a multiset // to store all possible values priority_queue< pair< int , int > > pq; // Iterate through all the values and // add it to the priority queue for ( int i = 0; i < n; i++) { // If the number is divisible by k // divide it by K and add to priority queue if (arr[i] % k == 0) pq.push(make_pair( arr[i] / k, i )); // Adding number as it is pq.push(make_pair( arr[i], i )); // Adding number after multiplying it by k pq.push(make_pair(arr[i] * k, i )); } // HashMap to keep track of current values map< int , int >mp; while (!pq.empty()) { pair< int , int >temp = pq.top(); pq.pop(); mp.insert(temp); // if for every index there is at-least // 1 value we calculate the answer if (mp.size() == n) { int min_value = INT_MAX; for ( auto x:mp) min_value=min(min_value, x.second); ans = min(ans, temp.first - min_value); } } // Returning the calculated answer return ans; } // Driver code int main() { // Input Array int arr[7] = { 1, 2, 3, 4, 5, 10, 7 }; int K = 5; // Size of the array int N = sizeof (arr)/ sizeof ( int ); // Printing final output cout << (calculateMinDiff(arr, K, N)); } // This code is contributed by ishayadav2918 |
Java
// Java implementation of the above approach import java.io.*; import java.util.*; class GfG { // Function to calculate Minimum // difference between maximum and // minimum value of the array private static int calculateMinDiff( int arr[], int k) { // Length of the array int n = arr.length; // Variable to store minimum difference int ans = Integer.MAX_VALUE; // PriorityQueue which is used as a multiset // to store all possible values PriorityQueue< int []> pq = new PriorityQueue<>(( int x[], int y[]) -> x[ 0 ] - y[ 0 ]); // Iterate through all the values and // add it to the priority queue for ( int i = 0 ; i < n; i++) { // If the number is divisible by k // divide it by K and add to priority queue if (arr[i] % k == 0 ) pq.add( new int [] { arr[i] / k, i }); // Adding number as it is pq.add( new int [] { arr[i], i }); // Adding number after multiplying it by k pq.add( new int [] { arr[i] * k, i }); } // HashMap to keep track of current values HashMap<Integer, Integer> map = new HashMap<>(); while (!pq.isEmpty()) { int temp[] = pq.poll(); map.put(temp[ 1 ], temp[ 0 ]); // if for every index there is at-least // 1 value we calculate the answer if (map.size() == n) { ans = Math.min(ans, temp[ 0 ] - Collections.min(map.values())); } } // Returning the calculated answer return ans; } // Driver code public static void main(String args[]) { // Input Array int arr[] = { 1 , 2 , 3 , 4 , 5 , 10 , 7 }; int K = 5 ; // Printing final output System.out.println(calculateMinDiff(arr, K)); } } |
Python3
# Python3 implementation of the above approach import sys # Function to calculate Minimum # difference between maximum and # minimum value of the array def calculateMinDiff(arr, k , n) : # Variable to store minimum difference ans = sys.maxsize # PriorityQueue which is used as a multiset # to store all possible values pq = [] # Iterate through all the values and # add it to the priority queue for i in range (n) : # If the number is divisible by k # divide it by K and add to priority queue if (arr[i] % k = = 0 ) : pq.append((arr[i] / / k, i )) # Adding number as it is pq.append((arr[i], i)) # Adding number after multiplying it by k pq.append((arr[i] * k, i)) pq.sort() pq.reverse() # HashMap to keep track of current values mp = {} while ( len (pq) > 0 ) : temp = pq[ 0 ] pq.pop( 0 ) mp[temp[ 0 ]] = temp[ 1 ] # if for every index there is at-least # 1 value we calculate the answer if ( len (mp) = = n) : min_value = sys.maxsize for x in mp : min_value = min (min_value, mp[x]) ans = min (ans, temp[ 0 ] - min_value - 1 ) # Returning the calculated answer return ans # Input Array arr = [ 1 , 2 , 3 , 4 , 5 , 10 , 7 ] K = 5 # Size of the array N = len (arr) # Printing final output print (calculateMinDiff(arr, K, N)) # This code is contributed by divyesh072019. |
C#
// C# implementation of the above approach using System; using System.Collections.Generic; class GFG { // Function to calculate Minimum // difference between maximum and // minimum value of the array static int calculateMinDiff( int [] arr, int k , int n) { // Variable to store minimum difference int ans = Int32.MaxValue; // PriorityQueue which is used as a multiset // to store all possible values List<Tuple< int , int >> pq = new List<Tuple< int , int >>(); // Iterate through all the values and // add it to the priority queue for ( int i = 0; i < n; i++) { // If the number is divisible by k // divide it by K and add to priority queue if (arr[i] % k == 0) pq.Add( new Tuple< int , int >( arr[i] / k, i )); // Adding number as it is pq.Add( new Tuple< int , int >( arr[i], i )); // Adding number after multiplying it by k pq.Add( new Tuple< int , int >(arr[i] * k, i )); } pq.Sort(); pq.Reverse(); // HashMap to keep track of current values Dictionary< int , int > mp = new Dictionary< int , int >(); while (pq.Count > 0) { Tuple< int , int > temp = pq[0]; pq.RemoveAt(0); mp[temp.Item1] = temp.Item2; // if for every index there is at-least // 1 value we calculate the answer if (mp.Count == n) { int min_value = Int32.MaxValue; foreach (KeyValuePair< int , int > x in mp) { min_value=Math.Min(min_value, x.Value); } ans = Math.Min(ans, temp.Item1 - min_value - 1); } } // Returning the calculated answer return ans; } // Driver code static void Main() { // Input Array int [] arr = { 1, 2, 3, 4, 5, 10, 7 }; int K = 5; // Size of the array int N = arr.Length; // Printing final output Console.WriteLine(calculateMinDiff(arr, K, N)); } } // This code is contributed by divyeshrabadiya07. |
Javascript
<script> // JavaScript implementation of the above approach // Function to calculate Minimum // difference between maximum and // minimum value of the array function calculateMinDiff(arr, k, n) { // Variable to store minimum difference let ans = Number.MAX_SAFE_INTEGER; // PriorityQueue which is used as a multiset // to store all possible values let pq = new Array(); // Iterate through all the values and // push it to the priority queue for (let i = 0; i < n; i++) { // If the number is divisible by k // divide it by K and push to priority queue if (arr[i] % k == 0) pq.push( new Array(Math.floor(arr[i] / k), i)); // pushing number as it is pq.push( new Array(arr[i], i)); // pushing number after multiplying it by k pq.push( new Array(arr[i] * k, i)); } pq.sort((a, b) => a[0] - b[0]); pq.reverse(); // HashMap to keep track of current values let mp = new Map(); while (pq.length > 0) { let temp = pq[0]; pq.shift(); mp.set(temp[0], temp[1]); // if for every index there is at-least // 1 value we calculate the answer if (mp.size == n) { let min_value = Number.MAX_SAFE_INTEGER; for (let x of mp) { min_value = Math.min(min_value, x[1]); } ans = Math.min(ans, temp[1] - min_value); } } // Returning the calculated answer return ans; } // Driver code // Input Array let arr = [1, 2, 3, 4, 5, 10, 7]; let K = 5; // Size of the array let N = arr.length; // Printing final output document.write(calculateMinDiff(arr, K, N)); // This code is contributed by gfgking </script> |
5
Time Complexity: O(NlogN)
Auxiliary Space: O(N), where N is the size of the input array. This is because the priority queue and the map are the two data structures that are being used to store the elements of the input array, and the size of these data structures can be at most equal to the size of the input array.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!