You are given an array nums
of n
positive integers.
You can perform two types of operations on any element of the array any number of times:
2
.
[1,2,3,4]
, then you can do this operation on the last element, and the array will be [1,2,3,2].
2
.
[1,2,3,4]
, then you can do this operation on the first element, and the array will be [2,2,3,4].
The deviation of the array is the maximum difference between any two elements in the array.
Return the minimum deviation the array can have after performing some number of operations.
Example 1:
Input: nums = [1,2,3,4] Output: 1 Explanation: You can transform the array to [1,2,3,2], then to [2,2,3,2], then the deviation will be 3 - 2 = 1.
Example 2:
Input: nums = [4,1,5,20,3] Output: 3 Explanation: You can transform the array after two operations to [4,2,5,5,3], then the deviation will be 5 - 2 = 3.
Example 3:
Input: nums = [2,10,8] Output: 3
Constraints:
n == nums.length
2 <= n <= 5 * 104
1 <= nums[i] <= 109
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force method for this problem involves checking every possible combination of changes to our numbers. We want to find the smallest difference between the biggest and smallest number after doing some changes. We'll explore all possible changes, one at a time.
Here's how the algorithm would work step-by-step:
def minimize_deviation_brute_force(numbers):
min_deviation = float('inf')
def calculate_deviation(current_numbers):
return max(current_numbers) - min(current_numbers)
def backtrack(index, current_numbers):
nonlocal min_deviation
min_deviation = min(min_deviation, calculate_deviation(current_numbers))
if index == len(numbers):
return
original_number = numbers[index]
current_number = current_numbers[index]
# Explore doubling if odd
if original_number % 2 != 0:
doubled_numbers = current_numbers[:]
doubled_numbers[index] = original_number * 2
backtrack(index + 1, doubled_numbers)
# Explore halving if even
if current_number % 2 == 0:
halved_numbers = current_numbers[:]
halved_numbers[index] = current_number // 2
# Only proceed if halving leads to deviation decrease
if calculate_deviation(halved_numbers) < calculate_deviation(current_numbers):
backtrack(index + 1, halved_numbers)
# If the number is even after doubling or halving, further explore
if current_number != original_number and current_number % 2 == 0:
halved_numbers = current_numbers[:]
halved_numbers[index] = current_number // 2
# Only proceed if halving leads to deviation decrease
if calculate_deviation(halved_numbers) < calculate_deviation(current_numbers):
backtrack(index + 1, halved_numbers)
backtrack(index + 1, current_numbers)
backtrack(0, numbers[:])
return min_deviation
The key idea is to focus on reducing the largest number and increasing the smallest number in the given collection. By strategically applying allowable operations, we bring the numbers closer together, which shrinks the difference between the largest and smallest.
Here's how the algorithm would work step-by-step:
def minimize_deviation(nums):
numbers_set = set()
for number in nums:
if number % 2 != 0:
numbers_set.add(number * 2)
else:
numbers_set.add(number)
deviation = float('inf')
# The smallest number.
smallest_number = min(numbers_set)
# We repeatedly reduce the largest number.
while True:
largest_number = max(numbers_set)
deviation = min(deviation, largest_number - smallest_number)
# If the largest number is even, we can halve it.
if largest_number % 2 == 0:
numbers_set.remove(largest_number)
numbers_set.add(largest_number // 2)
smallest_number = min(numbers_set)
# Otherwise, we can't reduce further.
else:
break
return deviation
Case | How to Handle |
---|---|
Empty input array | Return infinity or an error, as no deviation can be calculated. |
Array with only one element | Return 0, as there's only one number and no deviation. |
Array with all identical elements | The deviation will be 0, as the maximum and minimum are the same. |
Array with large numbers leading to potential integer overflow when doubling | Use a data type that can handle larger values, such as long, to prevent overflow. |
Array where all even numbers are at their minimum and all odd numbers are at their maximum possible values after operations. | The deviation is minimized when all numbers are close to each other, so calculate the deviation after even number division and odd number multiplication. |
Array with a very skewed distribution of numbers (e.g., one very large number and many small numbers) | The maximum deviation can be very large, potentially affecting performance and requiring careful handling of data types. |
Maximum sized input array | Ensure that the algorithm's time and space complexity are efficient enough to handle large inputs. |
Array contains negative numbers | Convert all numbers to positive during initial step by getting their absolute value to avoid unexpected results. |