Grokking Data Structures & Algorithms for Coding Interviews
Ask Author
Back to course home

0% completed

Vote For New Content
Solution: Minimize the Maximum of Two Arrays
Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Problem Statement

Given divisor1, divisor2, uniqueCnt1, and uniqueCnt2 integers, find the smallest possible maximum integer that could be present in either array after they are filled according to the below conditions.

  • You can take two arrays arr1 and arr2 which are initially empty.
  • arr1 contains total uniqueCnt1 different positive integers, each of them is not divisible by divisor1.
  • arr2 contains total uniqueCnt2 different positive integers, each of them is not divisible by divisor2.
  • There are no common integers in both arrays.

Examples

Example 1:

  • Input: uniqueCnt1 = 2, divisor1 = 2, uniqueCnt2 = 2, divisor2 = 3
  • Expected Output: 4
  • Explanation: The optimal arrays could be arr1 = [1, 3] (numbers not divisible by 2) and arr2 = [2, 4] (numbers not divisible by 3). The maximum number among both arrays is 4.

Example 2:

  • Input: uniqueCnt1 = 3, divisor1 = 3, uniqueCnt2 = 4, divisor2 = 4
  • Expected Output: 7
  • Explanation: Possible arrays are arr1 = [1, 2, 4] and arr2 = [3, 5, 6, 7]. The highest integer used is 7.

Example 3:

  • Input: uniqueCnt1 = 1, divisor1 = 7, uniqueCnt2 = 1, divisor2 = 10
  • Expected Output: 2
  • Explanation: We can use arr1 = [1] (since it's not divisible by 7) and arr2 = [2] (since it's not divisible by 10). The highest integer here is 2.

Constraints:

  • 2 <= divisor1, divisor2 <= 10<sup>5</sup>
  • 1 <= uniqueCnt1, uniqueCnt2 < 10<sup>9</sup>
  • 2 <= uniqueCnt1 + uniqueCnt2 <= 10<sup>9</sup>

Solution

To solve this problem, the approach involves generating two sets of integers for arr1 and arr2 that adhere to their respective divisibility conditions. This process can be streamlined using a binary search method to determine the smallest possible maximum integer in an efficient manner. By setting an upper and lower bound and validating each midpoint in the binary search, we can check if it's possible to meet the conditions with the current maximum value.

This method is both efficient and effective, as it systematically narrows down the potential maximum value without having to explicitly generate each possible combination of arrays.

Step-by-Step Algorithm

  1. Initialize Variables:

    • low is set to the sum of uniqueCnt1 and uniqueCnt2 to ensure there are enough integers available to meet the minimum requirements of both sets.
    • high is set to a divisor1 * divisor2 * uniqueCnt1 * uniqueCnt2, which acts as an initial upper bound for the binary search.
  2. Compute Least Common Multiple (LCM):

    • Calculate the least common multiple (LCM) of divisor1 and divisor2 using the gcd function. The LCM is needed to determine how many numbers are divisible by both divisors.
  3. Binary Search:

    • Perform a binary search between low and high. In each iteration:
      • Calculate mid, which is the average of low and high.
      • Compute countBoth, the count of numbers up to mid that are divisible by both divisor1 and divisor2.
  4. Validity Check:

    • Check if the current mid can accommodate all required conditions:
      • Ensure there are enough numbers after removing those divisible by both divisors (mid - countBoth) to fill both sets.
      • Ensure that after removing numbers divisible by divisor1, there are still at least uniqueCnt1 numbers left.
      • Ensure that after removing numbers divisible by divisor2, there are still at least uniqueCnt2 numbers left.
  5. Adjust Search Bounds:

    • If the conditions are satisfied, reduce high to mid - 1 to search for a potentially smaller maximum.
    • If not, increase low to mid + 1 to eliminate too small values.
  6. Determine Result:

    • The loop exits when low exceeds high, and low will hold the minimum maximum integer that satisfies all conditions.

Algorithm Walkthrough

Let's consider the Input: uniqueCnt1 = 3, divisor1 = 3, uniqueCnt2 = 4, divisor2 = 4

Initialization:

  • low = 7, high = 144, lcm = 12.

Binary Search Process:

  • Iteration 1:

    • mid = 75.
    • countBoth = 6.
    • Check conditions:
      • mid - countBoth = 69 (Condition 1: Satisfied).
      • mid - (mid / 3) = 50 (Condition 2: Satisfied).
      • mid - (mid / 4) = 57 (Condition 3: Satisfied).
    • Conditions met, update high = 74.
  • Iteration 2:

    • mid = 40.
    • countBoth = 3.
    • Check conditions:
      • mid - countBoth = 37 (Condition 1: Satisfied).
      • mid - (mid / 3) = 27 (Condition 2: Satisfied).
      • mid - (mid / 4) = 30 (Condition 3: Satisfied).
    • Conditions met, update high = 39.
  • Iteration 3:

    • mid = 23.
    • countBoth = 1.
    • Check conditions:
      • mid - countBoth = 22 (Condition 1: Satisfied).
      • mid - (mid / 3) = 15 (Condition 2: Satisfied).
      • mid - (mid / 4) = 17 (Condition 3: Satisfied).
    • Conditions met, update high = 22.
  • Iteration 4:

    • mid = 14.
    • countBoth = 1.
    • Check conditions:
      • mid - countBoth = 13 (Condition 1: Satisfied).
      • mid - (mid / 3) = 9 (Condition 2: Satisfied).
      • mid - (mid / 4) = 10 (Condition 3: Satisfied).
    • Conditions met, update high = 13.
  • Iteration 5:

    • mid = 10.
    • countBoth = 0.
    • Check conditions:
      • mid - countBoth = 10 (Condition 1: Satisfied).
      • mid - (mid / 3) = 7 (Condition 2: Satisfied).
      • mid - (mid / 4) = 8 (Condition 3: Satisfied).
    • Conditions met, update high = 9.
  • Iteration 6:

    • mid = 8.
    • countBoth = 0.
    • Check conditions:
      • mid - countBoth = 8 (Condition 1: Satisfied).
      • mid - (mid / 3) = 6 (Condition 2: Satisfied).
      • mid - (mid / 4) = 6 (Condition 3: Just satisfied).
    • Conditions met, update high = 7.
  • Iteration 7:

    • mid = 7.
    • countBoth = 0.
    • Check conditions:
      • mid - countBoth = 7 (Condition 1: Just satisfied).
      • mid - (mid / 3) = 5 (Condition 2: Satisfied).
      • mid - (mid / 4) = 5 (Condition 3: Satisfied).
    • Conditions met, update high = 6.

Conclusion:

  • After Iteration 7, low and high will adjust such that low > high after the next step where low remains 7 and high becomes 6.
  • The smallest value that satisfies all conditions is 7. This becomes the output of the binary search, representing the minimum maximum number that can be accommodated in both arrays under the given constraints.

Code

Python3
Python3

. . . .

Complexity Analysis

Time Complexity

The time complexity of the minimizeSet function primarily revolves around the binary search mechanism used to narrow down the potential maximum integer:

  • Binary Search: The loop runs as long as low is less than or equal to high. Each iteration approximately halves the search space, making the time complexity logarithmic. Given that the high is initialized to divisor1 * divisor2 * uniqueCnt1 * uniqueCnt2, the number of iterations is around O(log(divisor1 * divisor2 * uniqueCnt1 * uniqueCnt2)), which is about 40.
  • GCD Calculation: The time complexity of the Euclidean algorithm to compute the GCD is O(log(min(a, b))), where a and b are the inputs to the GCD function. However, this computation is done once and hence does not significantly impact the overall complexity.

Overall, the time complexity of the minimizeSet function is O(log(maxRange)), where maxRange is the difference between the initial high and low values, scaled logarithmically by the binary search.

Space Complexity

The space complexity of the solution is O(1) as the function utilizes a fixed amount of space for its variables (low, high, mid, countBoth, count1, count2, and lcm), and there are no dynamically sized data structures used.

.....

.....

.....

Like the course? Get enrolled and start learning!

Table of Contents

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible

Contents are not accessible