Talentd
FleetCode
Make and follow sheets.Sign in

Reduction Operations to Make the Array Elements Equal solution and explanation

MediumArraySorting6 min read72.7% acceptanceUpdated 9 Apr 2026
Reduction Operations to Make the Array Elements Equal | Intuition | Leetcode-1887codestorywithMIK · 13:54 · 4K viewsWatch on YouTube
9 more videos on this problem
  1. Reduction Operations to Make the Array Elements Equal | Intuition | Leetcode-1887codestorywithMIK · 13:54 · 4K views
  2. [Leetcode] 1887. Reduction Operations to Make the Array Elements Equal羅油膩GO工程師頻道 · 7:17 · 1K views
  3. Leetcode 1887 | Reduction Operations to Make the Array Elements EqualSandip Jana · 5:00 · 1K views
  4. 1887. Reduction Operations to Make the Array Elements Equal | Priority Queue | SortingAryan Mittal · 10:12 · 1K views
  5. Reduction Operations to Make the Array Elements Equal | LeetCode Weekly Contest 244 | Coders CampCoders Camp · 6:51 · 897 views
  6. ✅ Reduction Operations to Make the Array Elements Equal - Modified Counting Sort - LeetCode 1887Leet Logics · 8:26 · 542 views
  7. 1887. Reduction Operations to Make the Array Elements Equal (Leetcode Medium)Programming Live with Larry · 5:49 · 420 views
  8. Daily Leetcode #1328: Nov 19, 2023 - 1887. Reduction Operations to Make the Array Elements EqualProgramming Live with Larry · 10:00 · 248 views
  9. Solving LeetCode 1887 Reduction Operations to Make the Array Elements Equal | Array | IntuitiveCode Harmony · 9:47 · 215 views
  10. Reduction Operations to Make the Array Elements Equal - LeetCode 1887 - PythonAlpha-Code · 11:29 · 159 views

The problem

Given an integer array nums, your goal is to make all elements in nums equal. To complete one operation, follow these steps:

  1. Find the largest value in nums. Let its index be i (0-indexed) and its value be largest. If there are multiple elements with the largest value, pick the smallest i.
  2. Find the next largest value in nums strictly smaller than largest. Let its value be nextLargest.
  3. Reduce nums[i] to nextLargest.

Return the number of operations to make all elements in nums equal.

Example 1:

Input: nums = [5,1,3]
Output: 3
Explanation: It takes 3 operations to make all elements in nums equal:
1. largest = 5 at index 0. nextLargest = 3. Reduce nums[0] to 3. nums = [3,1,3].
2. largest = 3 at index 0. nextLargest = 1. Reduce nums[0] to 1. nums = [1,1,3].
3. largest = 3 at index 2. nextLargest = 1. Reduce nums[2] to 1. nums = [1,1,1].

Example 2:

Input: nums = [1,1,1]
Output: 0
Explanation: All elements in nums are already equal.

Example 3:

Input: nums = [1,1,2,2,3]
Output: 4
Explanation: It takes 4 operations to make all elements in nums equal:
1. largest = 3 at index 4. nextLargest = 2. Reduce nums[4] to 2. nums = [1,1,2,2,2].
2. largest = 2 at index 2. nextLargest = 1. Reduce nums[2] to 1. nums = [1,1,1,2,2].
3. largest = 2 at index 3. nextLargest = 1. Reduce nums[3] to 1. nums = [1,1,1,1,2].
4. largest = 2 at index 4. nextLargest = 1. Reduce nums[4] to 1. nums = [1,1,1,1,1].

Constraints:

  • 1 <= nums.length <= 5 * 104
  • 1 <= nums[i] <= 5 * 104

Approach overview

Problem Overview: You are given an array of integers. In one operation, you pick the largest value and reduce it to the next smaller distinct value in the array. The goal is to compute the minimum number of operations required to make all elements equal.

Approach 1: Sorting and Iteration (Time: O(n log n), Space: O(1))

Sort the array so equal values are grouped and larger numbers appear later. While scanning the sorted array from left to right, each time you encounter a new distinct value, every element to its right will eventually require one additional reduction step. Track the index i and whenever nums[i] != nums[i-1], add i to the total operations. The insight: each distinct level of value introduces another layer of reductions for all larger elements. Sorting simplifies the comparison logic and avoids repeatedly simulating operations.

This approach works well in practice because the algorithm becomes a single pass after sorting. The implementation is concise and uses only constant extra space beyond the input array. The main cost comes from sorting, which takes O(n log n). See more patterns like this in sorting and array problems.

Approach 2: Counting and Aggregating (Time: O(n log k), Space: O(k))

Instead of sorting the entire array, count the frequency of each distinct value using a map or counting structure. Let k be the number of unique values. Sort the unique keys and process them from smallest to largest. Maintain a running count of how many elements are greater than the current value. Each time you move to the next larger value level, all elements above it require one additional reduction operation.

The key idea is aggregating reductions by value groups rather than by individual elements. Frequencies allow you to compute how many elements participate in each reduction layer. This reduces repeated work and keeps the algorithm efficient when the number of unique values is small. The complexity becomes O(n) to build the frequency map plus O(k log k) to sort unique values.

Recommended for interviews: The sorting and iteration approach is typically expected. It is simple, easy to reason about, and directly models how reduction layers accumulate across distinct values. Interviewers often want to see the insight that each new distinct value contributes operations equal to the number of elements already processed. The counting approach demonstrates stronger optimization thinking when discussing alternatives.

Approach 1: Approach 1: Sorting and Iteration

To solve this problem, we can first sort the array. After sorting, for each distinct number except the smallest one, count how many times smaller numbers need to be stepped up to equal the larger ones. Iterate over the sorted array and accumulate these steps until all numbers are equal.

def reduction_operations(nums):
    nums.sort()
    operations = 0
    distinct_count = 0
    for i in range(1, len(nums)):
        if nums[i] != nums[i - 1]:
            distinct_count += 1
        operations += distinct_count
    return operations

print(reduction_operations([5, 1, 3]))
import java.util.Arrays;

public class Solution {
    public int reductionOperations(int[] nums) {
        Arrays.sort(nums);
        int operations = 0, distinctCount = 0;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] != nums[i - 1]) {
                distinctCount++;
            }
            operations += distinctCount;
        }
        return operations;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = {5, 1, 3};
        System.out.println(solution.reductionOperations(nums));
    }
}
#include <iostream>
#include <vector>
#include <algorithm>

int reductionOperations(std::vector<int>& nums) {
    std::sort(nums.begin(), nums.end());
    int operations = 0, distinctCount = 0;
    for (int i = 1; i < nums.size(); i++) {
        if (nums[i] != nums[i - 1]) {
            distinctCount++;
        }
        operations += distinctCount;
    }
    return operations;
}

int main() {
    std::vector<int> nums = {5, 1, 3};
    std::cout << reductionOperations(nums) << std::endl;
    return 0;
}
function reductionOperations(nums) {
    nums.sort((a, b) => a - b);
    let operations = 0;
    let distinctCount = 0;
    for (let i = 1; i < nums.length; i++) {
        if (nums[i] !== nums[i - 1]) {
            distinctCount++;
        }
        operations += distinctCount;
    }
    return operations;
}

console.log(reductionOperations([5, 1, 3]));
#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int reductionOperations(int* nums, int numsSize) {
    qsort(nums, numsSize, sizeof(int), compare);
    int operations = 0, distinctCount = 0;
    for (int i = 1; i < numsSize; i++) {
        if (nums[i] != nums[i - 1]) {
            distinctCount++;
        }
        operations += distinctCount;
    }
    return operations;
}

int main() {
    int nums[] = {5, 1, 3};
    int size = sizeof(nums) / sizeof(nums[0]);
    printf("%d\n", reductionOperations(nums, size));
    return 0;
}
using System;

public class Solution {
    public int ReductionOperations(int[] nums) {
        Array.Sort(nums);
        int operations = 0, distinctCount = 0;
        for (int i = 1; i < nums.Length; i++) {
            if (nums[i] != nums[i - 1]) {
                distinctCount++;
            }
            operations += distinctCount;
        }
        return operations;
    }

    public static void Main(string[] args) {
        Solution solution = new Solution();
        int[] nums = {5, 1, 3};
        Console.WriteLine(solution.ReductionOperations(nums));
    }
}

In Python, we use the list sort method to order elements, then traverse through the sorted list while counting distinct numbers. This determines how many operations are needed by incrementing the operations count based on distinct elements.

Complexity

Time Complexity: O(n log n) from sorting, Space Complexity: O(1).

Try this approach in the editor

Approach 2: Approach 2: Counting and Aggregating

This approach involves counting the duplicates of each number without explicitly sorting. By iterating from the maximum value to the minimum, we calculate how many numbers need to be converted at each step by leveraging the array structure and gaps between numbers.

def reduction_operations(nums):
    count = [0] * 50001
    for num in nums:
        count[num] += 1
    operations = total = 0
    for i in range(50000, 0, -1):
        if count[i] > 0:
            operations += total
            total += count[i]
    return operations

print(reduction_operations([5, 1, 3]))
public class Solution {
    public int reductionOperations(int[] nums) {
        int[] count = new int[50001];
        for (int num : nums) {
            count[num]++;
        }
        int operations = 0, total = 0;
        for (int i = 50000; i > 0; i--) {
            if (count[i] != 0) {
                operations += total;
                total += count[i];
            }
        }
        return operations;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        int[] nums = {5, 1, 3};
        System.out.println(solution.reductionOperations(nums));
    }
}
#include <iostream>
#include <vector>

int reductionOperations(std::vector<int>& nums) {
    std::vector<int> count(50001, 0);
    for (int num : nums) {
        count[num]++;
    }
    int operations = 0, total = 0;
    for (int i = 50000; i > 0; i--) {
        if (count[i]) {
            operations += total;
            total += count[i];
        }
    }
    return operations;
}

int main() {
    std::vector<int> nums = {5, 1, 3};
    std::cout << reductionOperations(nums) << std::endl;
    return 0;
}
function reductionOperations(nums) {
    let count = Array(50001).fill(0);
    for (let num of nums) {
        count[num]++;
    }
    let operations = 0, total = 0;
    for (let i = 50000; i > 0; i--) {
        if (count[i] > 0) {
            operations += total;
            total += count[i];
        }
    }
    return operations;
}

console.log(reductionOperations([5, 1, 3]));
#include <stdio.h>

int reductionOperations(int* nums, int numsSize) {
    int count[50001] = {0};
    for (int i = 0; i < numsSize; i++) {
        count[nums[i]]++;
    }
    int operations = 0, total = 0;
    for (int i = 50000; i > 0; i--) {
        if (count[i]) {
            operations += total;
            total += count[i];
        }
    }
    return operations;
}

int main() {
    int nums[] = {5, 1, 3};
    int size = sizeof(nums) / sizeof(nums[0]);
    printf("%d\n", reductionOperations(nums, size));
    return 0;
}
using System;

public class Solution {
    public int ReductionOperations(int[] nums) {
        int[] count = new int[50001];
        foreach (int num in nums) {
            count[num]++;
        }
        int operations = 0, total = 0;
        for (int i = 50000; i > 0; i--) {
            if (count[i] > 0) {
                operations += total;
                total += count[i];
            }
        }
        return operations;
    }

    public static void Main(string[] args) {
        Solution solution = new Solution();
        int[] nums = {5, 1, 3};
        Console.WriteLine(solution.ReductionOperations(nums));
    }
}

This Python solution initializes a list of zeros, counting the frequency of each element. By iterating from maximum value downwards, it computes the number of necessary operations by effectively using cumulative frequency of encountered elements.

Complexity

Time Complexity: O(n + k), Space Complexity: O(k).

Try this approach in the editor

Approach 3: Sorting

We first sort the array nums, then iterate from the second element of the array. If the current element is not equal to the previous element, we increment cnt, indicating the number of operations needed to reduce the current element to the minimum value. Then we add cnt to ans and continue to the next element.

The time complexity is O(n times log n), and the space complexity is O(log n). Here, n is the length of the array nums.

function reductionOperations(nums: number[]): number {
    nums.sort((a, b) => a - b);
    let [ans, cnt] = [0, 0];
    for (let i = 1; i < nums.length; ++i) {
        if (nums[i] !== nums[i - 1]) {
            ++cnt;
        }
        ans += cnt;
    }
    return ans;
}
func reductionOperations(nums []int) (ans int) {
	sort.Ints(nums)
	cnt := 0
	for i, x := range nums[1:] {
		if x != nums[i] {
			cnt++
		}
		ans += cnt
	}
	return
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Approach 1: Sorting and Iteration

Time Complexity: O(n log n) from sorting, Space Complexity: O(1).

Approach 2: Counting and Aggregating

Time Complexity: O(n + k), Space Complexity: O(k).

Sorting–

Complexity analysis

ApproachTimeSpaceWhen to Use
Sorting and IterationO(n log n)O(1)General case. Simple implementation and commonly expected in interviews.
Counting and AggregatingO(n log k)O(k)When the number of distinct values is much smaller than n and frequency aggregation is convenient.

Frequently asked questions

Is Reduction Operations to Make the Array Elements Equal easy or hard?

LeetCode classifies this problem as Medium. The challenge is recognizing that each distinct value level contributes reductions for all larger elements. Once that pattern is identified, the implementation becomes a straightforward sorting and counting pass.

Reduction Operations to Make the Array Elements Equal Python/Java solution

In Python or Java, the standard solution sorts the array and iterates once. Whenever nums[i] differs from nums[i-1], add i to the operation count. This concise logic works the same across languages like Python, Java, C++, and JavaScript.

How to solve Reduction Operations to Make the Array Elements Equal in O(n)?

An almost linear approach uses a frequency map to count occurrences of each value, then processes unique values in sorted order. Building the map is O(n), and operations are aggregated using counts of larger elements. The total complexity becomes O(n + k log k), where k is the number of distinct values.

What is the best approach for Reduction Operations to Make the Array Elements Equal?

The most common approach sorts the array and scans it once. Every time a new distinct value appears at index i, you add i operations because all larger elements must eventually be reduced through this level. This produces an O(n log n) time solution with O(1) extra space and is the method most interviewers expect.

Is Reduction Operations to Make the Array Elements Equal asked at Google/Amazon/Meta?

This problem reflects common interview patterns around sorting and counting reductions across value groups. Similar problems appear in interviews at companies like Amazon and Google where candidates must recognize patterns involving sorted arrays and cumulative operations.

What data structure is used in Reduction Operations to Make the Array Elements Equal?

The primary data structures are arrays and optionally a hash map for counting frequencies. The sorting-based approach works directly on the array, while the counting approach stores value frequencies before aggregating operations across distinct numbers.

What is the time complexity of Reduction Operations to Make the Array Elements Equal?

The typical solution runs in O(n log n) time due to sorting the array. After sorting, the algorithm performs a single linear scan to accumulate operations. Space complexity is O(1) if sorting is done in place, aside from the input array.

Comments

Now write it yourselfClose this page and solve Reduction Operations to Make the Array Elements Equal in the editor, without looking.
Practise Reduction Operations to Make the Array Elements Equal