Minimize the Maximum Value in Two Arrays
Last Updated : 08 Jul, 2024
Given two empty arrays arr1[] and arr2[]. You need to add positive integers to these arrays such that they satisfy the following conditions:
- arr1 contains k1 distinct positive integers, each of which is not divisible by d1.
- arr2 contains k2 distinct positive integers, each of which is not divisible by d2.
- No integer is present in both arr1 and arr2.
Given the values of d1, d2, k1, and k2, the task is to return the minimum possible maximum value that can be present in either arr1 or arr2.
Example:
Input: d1 = 2, d2 = 7, k1 = 1, k2 = 3
Output: 4
Explanation:
We can distribute the first 4 natural numbers into arr1 and arr2. arr1 = [1] and arr2 = [2,3,4]. We can see that both arrays satisfy all the conditions. Since the maximum value is 4, we return it.
Input: d1 = 3, d2 = 5, k1 = 2, k2 = 1
Output: 3
Explanation:
Here arr1 = [1,2], and arr2 = [3] satisfy all conditions. Since the maximum value is 3, we return it.
Approach:
When you have to minimise/maximise, there's a very high chance you can binary search on the answer. Here if we know a number X provides us enough numbers to fulfill both conditions, then we can simply look for a number smaller than X which might satisfy the condition, if not we will look for a larger number. Now the question is to just check if a number X satisfies the condition or not.
Now to check if a number X satisfies the condition or not, we will first calculate how many numbers are there from 1...X that are divisible by d1 and d2. We can find out this by dividing X by d1, i.e. divisibleByD1 = X / d1. Then we can do the same for d2, i.e. divisibleByD2 = X / d2. Now the number of integers that we can add to the first array are elements1 = X - divisibleByD1 and number of elements we can add to the second array are elements2 = X - divisibleByD2. If you notice here there might be an overlap. For e.g. d1 = 4 and d2 = 6 and X = 13. Here divisibleByD1 = 3 { 4, 8, 12 } and divisibleByD2 = 2 { 6, 12 }. These are the elements that we cannot use in either array1 or array2. But there's an overlap of 12 which we can't use in either of the arrays but we've calculated it twice. To solve this, we will also calculate the number of elements divisible by both d1 and d2 (which is number of elements divisible by lcm(d1, d2)) (this finds out the overlapping elements). Now X will satisfy the condition if k1 <= elements1 && k2 <= elements2 && k1 + k2 <= X - (X / LCM).
Steps-by-step approach:
- Calculate LCM: Multiply d1 and d2 and divide by their greatest common divisor (GCD).
- Iterate Multiples: Go through all multiples of the LCM up to the sum of uc1 and uc2.
- Count Elements: For each multiple, count how many elements are divisible by d1 and d2.
- Update Minimum: If the total count is less than the current minimum, update the minimum.
- Return Minimum: Return the minimum number of elements found.
Below is the implementation of the above approach:
C++ #include <algorithm> #include <iostream> #include <vector> using namespace std; // Function to find the minimum number of elements in the // set int minimizeSet(int d1, int d2, int k1, int k2) { // Calculate the least common multiple (LCM) of d1 and // d2 int lcm = d1 * d2 / __gcd(d1, d2); // Initialize the minimum number of elements to the sum // of k1 and k2 int minElements = k1 + k2; // Iterate over all multiples of the LCM less than or // equal to k1 + k2 for (int i = 1; i * lcm <= k1 + k2; ++i) { // Calculate the number of elements divisible by d1 // and d2 int elementsDivisibleByDivisor1 = (k1 + i - 1) / i; int elementsDivisibleByDivisor2 = (k2 + i - 1) / i; // Update the minimum number of elements if // necessary minElements = min(minElements, elementsDivisibleByDivisor1 + elementsDivisibleByDivisor2 - i); } return minElements; } int main() { int d1 = 2, d2 = 7, k1 = 1, k2 = 3; int minElements = minimizeSet(d1, d2, k1, k2); cout << "Minimum number of elements: " << minElements << endl; return 0; }
Java import java.util.*; public class Main { // Function to find the minimum number of elements in // the set static int minimizeSet(int d1, int d2, int k1, int k2) { // Calculate the least common multiple (LCM) of d1 // and d2 int lcm = d1 * d2 / gcd(d1, d2); // Initialize the minimum number of elements to the // sum of k1 and k2 int minElements = k1 + k2; // Iterate over all multiples of the LCM less than // or equal to k1 + k2 for (int i = 1; i * lcm <= k1 + k2; ++i) { // Calculate the number of elements divisible by // d1 and d2 int elementsDivisibleByDivisor1 = (k1 + i - 1) / i; int elementsDivisibleByDivisor2 = (k2 + i - 1) / i; // Update the minimum number of elements if // necessary minElements = Math.min( minElements, elementsDivisibleByDivisor1 + elementsDivisibleByDivisor2 - i); } return minElements; } // Function to calculate the greatest common divisor // (GCD) static int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } public static void main(String[] args) { int d1 = 2, d2 = 7, k1 = 1, k2 = 3; int minElements = minimizeSet(d1, d2, k1, k2); System.out.println("Minimum number of elements: " + minElements); } } // This code is contributed by Shivam Gupta
Python import math # Function to find the minimum number of elements in the set def minimizeSet(d1, d2, k1, k2): # Calculate the least common multiple (LCM) of d1 and d2 lcm = d1 * d2 // math.gcd(d1, d2) # Initialize the minimum number of elements to the sum of k1 and k2 minElements = k1 + k2 # Iterate over all multiples of the LCM less than or equal to k1 + k2 for i in range(1, (k1 + k2) // lcm + 1): # Calculate the number of elements divisible by d1 and d2 elementsDivisibleByDivisor1 = (k1 + i - 1) // i elementsDivisibleByDivisor2 = (k2 + i - 1) // i # Update the minimum number of elements if necessary minElements = min(minElements, elementsDivisibleByDivisor1 + elementsDivisibleByDivisor2 - i) return minElements if __name__ == "__main__": d1 = 2 d2 = 7 k1 = 1 k2 = 3 minElements = minimizeSet(d1, d2, k1, k2) print(f"Minimum number of elements: {minElements}") # This code is contributed by Ayush Mishra
JavaScript // Function to find the greatest common divisor (GCD) of two numbers function gcd(a, b) { if (b === 0) return a; return gcd(b, a % b); } // Function to find the minimum number of elements in the set function minimizeSet(d1, d2, k1, k2) { // Calculate the least common multiple (LCM) of d1 and d2 const lcm = (d1 * d2) / gcd(d1, d2); // Initialize the minimum number of elements to the sum of k1 and k2 let minElements = k1 + k2; // Iterate over all multiples of the LCM less than or equal to k1 + k2 for (let i = 1; i * lcm <= k1 + k2; ++i) { // Calculate the number of elements divisible by d1 and d2 const elementsDivisibleByDivisor1 = Math.ceil(k1 / i); const elementsDivisibleByDivisor2 = Math.ceil(k2 / i); // Update the minimum number of elements if necessary minElements = Math.min(minElements, elementsDivisibleByDivisor1 + elementsDivisibleByDivisor2 - i); } return minElements; } // Driver code const d1 = 2, d2 = 7, k1 = 1, k2 = 3; const minElements = minimizeSet(d1, d2, k1, k2); console.log("Minimum number of elements:", minElements);
OutputMinimum number of elements: 4
Time complexity: O(k1+ k2)
Auxiliary Space: O(1)