Facebook Pixel

3736. Minimum Moves to Equal Array Elements III

EasyArrayMath
LeetCode ↗

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.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

How We Pick the Algorithm

Why Math / Bit Manipulation?

This problem maps to Math / Bit Manipulation through a short path in the full flowchart.

Tree orgraph?noMath / bitmanipulation?yesMath / BitManipulation

Each element must rise to the maximum value with only increments, giving the formula mx * n - sum(nums) in closed form.

Open in Flowchart

Intuition

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:

  1. Compute the length of the array n = len(nums).
  2. Find the maximum value mx = max(nums) and the sum of all elements s = sum(nums).
  3. 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 is 4, so mx = 4.

Scanning the array once to compute the sum:

  • 1 + 4 + 2 = 7, so s = 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 → needs 4 - 1 = 3 moves
  • nums[1] = 4 → needs 4 - 4 = 0 moves
  • nums[2] = 2 → needs 4 - 2 = 2 moves

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)
46
1class 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}
32
1class 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};
45
1/**
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}
28

Time and Space Complexity

  • Time Complexity: O(n), where n is the length of the array nums. The function calls max(nums) and sum(nums), each of which iterates through the entire array once, resulting in a linear time complexity. The remaining operations (computing mx * 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 - 1 elements by 1." This is equivalent to decrementing one element by 1, so the answer is sum(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 Roadmap
Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Get a Personalized Study Roadmap:

How 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

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More