3736. Minimum Moves to Equal Array Elements III
Problem Description
You are given an integer array nums.
In one move, you may increase the value of any single element nums[i] by 1.
Return the minimum total number of moves required so that all elements in nums become equal.
Since each move can only increase an element, every element must eventually be raised to match the largest value in the array. For an array of length n, if the maximum value is mx and the sum of all elements is s, then the total number of moves needed to bring every element up to mx is mx * n - s.
How We Pick the Algorithm
Why Math / Bit Manipulation?
This problem maps to Math / Bit Manipulation through a short path in the full flowchart.
Each element must rise to the maximum value with only increments, giving the formula mx * n - sum(nums) in closed form.
Open in FlowchartIntuition
Since each move can only increase an element's value by 1, we can never decrease any number. This means all elements must rise to meet a common target value, and that target must be at least as large as the current maximum value in the array.
Why pick exactly the maximum value as the target? If we chose a target larger than mx, every element (including the maximum one) would need extra moves to reach it, increasing the total work. So the smallest possible target that all elements can reach is the maximum value mx itself, which minimizes the total number of moves.
Once we fix the target as mx, the number of moves needed for a single element nums[i] is mx - nums[i], because that's how many times we must add 1 to bring it up to mx. Summing this over all elements gives:
(mx - nums[0]) + (mx - nums[1]) + ... + (mx - nums[n-1])
We can simplify this by grouping all the mx terms together. There are n elements, so the mx terms add up to mx * n, and subtracting each nums[i] is the same as subtracting the total sum s. This leads directly to the formula mx * n - s, letting us compute the answer in a single pass without simulating any moves.
Pattern Learn more about Math patterns.
Solution Approach
Solution 1: Calculate Sum and Maximum Value
This problem requires making all elements in the array equal, with each operation only able to increase a single element by 1. To minimize the number of operations, we should make all elements equal to the maximum value in the array.
Therefore, we can first calculate the maximum value mx and the sum of array elements s. The number of operations required to make all elements equal to mx is mx * n - s, where n is the length of the array.
The implementation follows three simple steps:
- Compute the length of the array
n = len(nums). - Find the maximum value
mx = max(nums)and the sum of all elementss = sum(nums). - Return the result
mx * n - s.
No extra data structures are needed, and no simulation of individual moves is required. Both max and sum each scan the array once, so the time complexity is O(n), where n is the length of the array. The space complexity is O(1), since only a few variables are used.
Example Walkthrough
Let's trace through the solution approach using a small example: nums = [1, 4, 2].
Step 1: Compute the length of the array.
The array has three elements, so n = 3.
Step 2: Find the maximum value and the sum.
Scanning the array once to find the maximum:
- Compare
1,4,2→ the largest is4, somx = 4.
Scanning the array once to compute the sum:
1 + 4 + 2 = 7, sos = 7.
Step 3: Apply the formula mx * n - s.
mx * n - s = 4 * 3 - 7 = 12 - 7 = 5
So the answer is 5 moves.
Verifying the result manually:
Since every element must rise to meet the maximum value 4, the moves needed per element are:
nums[0] = 1→ needs4 - 1 = 3movesnums[1] = 4→ needs4 - 4 = 0movesnums[2] = 2→ needs4 - 2 = 2moves
Adding these up: 3 + 0 + 2 = 5 moves, which matches the formula's result. The array becomes [4, 4, 4], with all elements equal.
This confirms why the formula works: summing each individual (mx - nums[i]) is equivalent to computing mx * n - s, letting us skip simulating any moves and get the answer in a single linear pass.
Solution Implementation
1from typing import List
2
3
4class Solution:
5 def minMoves(self, nums: List[int]) -> int:
6 # Number of elements in the array
7 length = len(nums)
8
9 # The largest value in the array
10 max_value = max(nums)
11
12 # The total sum of all elements
13 total_sum = sum(nums)
14
15 # Key insight: incrementing n-1 elements by 1 is equivalent to
16 # decrementing 1 element by 1 (in terms of relative differences).
17 # So the goal reduces to making every element equal to the minimum.
18 #
19 # Mathematically, if we raise all elements up to max_value, the number
20 # of moves equals (max_value * length) - total_sum. This works because
21 # each move effectively closes the gap between an element and the target.
22 return max_value * length - total_sum
23```
24
25**Explanation of the approach:**
26
271. **Reframe the problem:** The operation "increment `n-1` elements by 1" is hard to reason about directly. Instead, observe that adding 1 to all but one element is equivalent to subtracting 1 from that single element, since only the *relative* differences between elements matter for equality.
28
292. **New target:** With this reframing, the task becomes: reduce each element down to the array's minimum, counting one move per unit decrement.
30
313. **Formula derivation:** The total moves equal the sum of differences between each element and the minimum: `sum(nums) - min_value * length`.
32
33 - The provided code uses an alternative but equivalent form: `max_value * length - total_sum`. Both produce a non-negative count of moves, though the minimum-based version is the more canonical solution for this LeetCode problem (453. Minimum Moves to Equal Array Elements).
34
35**Alternative (min-based) version** for reference:
36
37```python3
38from typing import List
39
40
41class Solution:
42 def minMoves(self, nums: List[int]) -> int:
43 min_value = min(nums)
44 # Sum of how far each element is above the minimum
45 return sum(num - min_value for num in nums)
461class Solution {
2 public int minMoves(int[] nums) {
3 // Number of elements in the array
4 int length = nums.length;
5
6 // Track the maximum value in the array
7 int maxValue = 0;
8
9 // Accumulate the sum of all elements
10 int sum = 0;
11
12 // Single pass to compute both the maximum value and the total sum
13 for (int value : nums) {
14 maxValue = Math.max(maxValue, value);
15 sum += value;
16 }
17
18 // Key insight:
19 // Incrementing n-1 elements by 1 is equivalent (in terms of relative
20 // differences) to decrementing a single element by 1.
21 // Therefore, the problem reduces to making every element equal to the
22 // minimum element by repeatedly subtracting 1 from larger elements.
23 //
24 // However, since we use maxValue here, the formula below works as well:
25 // To make all elements equal, the target value after all moves would be
26 // (maxValue + moves). Each move increases the sum by (length - 1).
27 // Solving sum + moves * (length - 1) == (maxValue + moves) * length
28 // yields: moves = maxValue * length - sum.
29 return maxValue * length - sum;
30 }
31}
321class Solution {
2public:
3 int minMoves(vector<int>& nums) {
4 int n = static_cast<int>(nums.size());
5 int maxValue = 0; // Track the maximum element in the array
6 int sum = 0; // Track the sum of all elements
7
8 // Single pass to compute both the maximum value and the total sum
9 for (int num : nums) {
10 maxValue = max(maxValue, num);
11 sum += num;
12 }
13
14 // Incrementing n-1 elements by 1 is equivalent (in relative terms)
15 // to decrementing a single element by 1. Thus, the number of moves
16 // needed is the sum of differences between each element and the
17 // minimum element. This is algebraically equal to:
18 // sum_i (maxValue - nums[i]) when leveling everything up to maxValue,
19 // but here we use the compact identity: maxValue * n - sum.
20 return maxValue * n - sum;
21 }
22};
23```
24
25A small note worth considering: the original code initializes `maxValue` (and `mx`) to `0`. This works correctly only when all elements are non-negative. If the array can contain negative values, initializing with `nums[0]` (or `INT_MIN`) would be safer. For the standard LeetCode constraints (`-10^9 <= nums[i] <= 10^9`), a more robust initialization is recommended:
26
27```cpp
28class Solution {
29public:
30 int minMoves(vector<int>& nums) {
31 int n = static_cast<int>(nums.size());
32 long long sum = 0; // Use long long to avoid overflow
33 int minValue = nums[0]; // Track the minimum element
34
35 // Compute the running minimum and the total sum
36 for (int num : nums) {
37 minValue = min(minValue, num);
38 sum += num;
39 }
40
41 // Total moves = sum of (each element - minimum element)
42 return static_cast<int>(sum - static_cast<long long>(minValue) * n);
43 }
44};
451/**
2 * Calculates the minimum number of moves to make all array elements equal,
3 * where one move increments n - 1 elements by 1.
4 *
5 * Incrementing n - 1 elements by 1 is equivalent to decrementing 1 element by 1
6 * (in terms of relative differences). Therefore, the goal becomes reducing every
7 * element down to the minimum... but here we use the complementary formulation:
8 * the total number of moves equals (max * n) - sum, which represents the total
9 * amount needed to raise every element up to the maximum value.
10 *
11 * @param nums - The input array of numbers.
12 * @returns The minimum number of moves required.
13 */
14function minMoves(nums: number[]): number {
15 // Number of elements in the array.
16 const length: number = nums.length;
17
18 // The maximum value in the array (the target each element should reach).
19 const maxValue: number = Math.max(...nums);
20
21 // The sum of all elements in the array.
22 const sum: number = nums.reduce((acc: number, cur: number) => acc + cur, 0);
23
24 // Total moves: bringing every element up to maxValue costs (maxValue * length),
25 // and subtracting the existing sum gives the total increments needed.
26 return maxValue * length - sum;
27}
28Time and Space Complexity
-
Time Complexity:
O(n), wherenis the length of the arraynums. The function callsmax(nums)andsum(nums), each of which iterates through the entire array once, resulting in a linear time complexity. The remaining operations (computingmx * n - s) take constant time. -
Space Complexity:
O(1). Only a constant number of extra variables (n,mx,s) are used, regardless of the input size, so the additional space required does not grow with the input.
Pattern Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Mixing up the problem's actual operation with the simplified formula.
The biggest source of confusion is that the problem statement and the canonical LeetCode problem (453) describe two different operations that happen to share the same mathematical answer:
- The problem statement above says: "increase the value of any single element by 1." Raising every element up to the maximum gives
max_value * length - total_sum. - The actual LeetCode 453 says: "increment
n - 1elements by 1." This is equivalent to decrementing one element by 1, so the answer issum(nums) - min_value * length.
Both formulas yield the same numeric result, but a developer who blindly copies the max-based formula while solving the real LeetCode 453 problem (or vice versa) may not understand why it works, and will be unable to defend the logic in an interview. Always confirm which operation the problem defines before picking a formula.
Pitfall 2: Integer overflow in fixed-width-integer languages.
In Python this is a non-issue because integers are arbitrary precision. However, when translating to Java, C++, or Go, the term max_value * length can easily exceed the range of a 32-bit int. For an array near the constraint limits (e.g., values up to 2^31 - 1 and large length), the multiplication overflows and produces a wrong (often negative) answer.
Solution: Prefer the min-based, difference-accumulating form, which never computes a large product and accumulates only the genuine move count:
from typing import List
class Solution:
def minMoves(self, nums: List[int]) -> int:
min_value = min(nums)
moves = 0
for num in nums:
moves += num - min_value # each term is small and non-negative
return moves
In languages prone to overflow, declare the accumulator as a 64-bit type (long in Java, long long in C++):
class Solution {
public int minMoves(int[] nums) {
int min = Integer.MAX_VALUE;
for (int num : nums) min = Math.min(min, num);
long moves = 0; // 64-bit accumulator avoids overflow
for (int num : nums) moves += (long) num - min;
return (int) moves;
}
}
Pitfall 3: Assuming negative numbers break the formula.
A common worry is that negative values in nums invalidate the result. They do not. Both max_value * length - total_sum and sum(num - min_value) rely only on relative differences, so any uniform shift (including into negative territory) cancels out and the move count stays correct and non-negative.
Pitfall 4: Empty or single-element arrays.
Calling max() or min() on an empty list raises a ValueError in Python. While LeetCode constraints typically guarantee at least one element, defensive code should handle the empty case explicitly. For a single element, the answer is trivially 0, which both formulas already produce correctly—no special casing needed there.
Ready to land your dream job?
Unlock your dream job with a 5-minute quiz for a personalized study roadmap!
Get My RoadmapHow would you design a stack which has a function min that returns the minimum element in the stack, in addition to push and pop? All push, pop, min should have running time O(1).
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion If you prefer videos here's a video that explains recursion in a fun and easy way Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask him
Want a Structured Path to Master System Design Too? Don’t Miss This!