Given an integer array nums
of size n
, return the minimum number of moves required to make all array elements equal.
In one move, you can increment n - 1
elements of the array by 1
.
For example:
nums = [1,2,3]
Output: 3
Explanation: Only three moves are needed (remember each move increments two elements):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
nums = [1,1,1]
Output: 0
Explain your solution. What is the time complexity? What is the space complexity? What are some edge cases?
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 approach to this problem involves trying every possible combination of moves. We want to make all the numbers in the group the same, so we'll exhaustively explore incrementing different numbers until they all match.
Here's how the algorithm would work step-by-step:
def minimum_moves_brute_force(numbers):
minimum_number_of_moves = float('inf')
def solve(current_numbers, number_of_moves):
nonlocal minimum_number_of_moves
# Base case: all numbers are equal
if len(set(current_numbers)) <= 1:
minimum_number_of_moves = min(minimum_number_of_moves, number_of_moves)
return
# Optimization to prune search space
if number_of_moves >= minimum_number_of_moves:
return
for index in range(len(current_numbers)):
# Try incrementing each number by one
new_numbers = current_numbers[:]
new_numbers[index] += 1
# Recursively call solve with the new numbers and incremented moves
solve(new_numbers, number_of_moves + 1)
solve(numbers, 0)
return minimum_number_of_moves
The key insight is to focus on how each move affects the difference between the numbers. Instead of incrementing multiple numbers, consider the opposite: decrementing one number, since both achieve the same relative difference between the elements. The optimal strategy is to figure out how many times you need to decrement each element until they all equal the smallest element.
Here's how the algorithm would work step-by-step:
def minimum_moves_to_equal_array_elements(numbers):
minimum_number = min(numbers)
#Find the smallest number. All numbers must
#eventually equal this value.
total_moves = 0
for number in numbers:
#Calculate the number of moves required for
#the current number to reach the minimum.
difference = number - minimum_number
total_moves += difference
#Return the total moves needed to equalize.
return total_moves
Case | How to Handle |
---|---|
Empty or null input array | Return 0 since no moves are needed on an empty array. |
Array with one element | Return 0, as all elements are already equal. |
Array with all elements already equal | Return 0, as no moves are required. |
Array with large positive integers | The summation in the formula could lead to integer overflow; use long to store the sum or calculate the difference between each element and the minimum to avoid large sum. |
Array with large number of elements (performance) | The O(n) solution based on sum and minimum element scales linearly, so it should be efficient even for large arrays. |
Array containing negative numbers | The solution works correctly with negative numbers since we are only interested in the difference between the elements and the minimum. |
Array with mix of large positive and negative integers | The solution is still correct because we are summing differences from the smallest element. |
Integer overflow during calculation of sum or intermediate steps | Use 64-bit integers (long) to prevent overflow when summing elements or calculating differences. |