Given an array arr and a function fn, return a sorted array sortedArr. You can assume fn only returns numbers and those numbers determine the sort order of sortedArr. sortedArr must be sorted in ascending order by fn output.
You may assume that fn will never duplicate numbers for a given array.
Example 1:
Input: arr = [5, 4, 1, 2, 3], fn = (x) => x Output: [1, 2, 3, 4, 5] Explanation: fn simply returns the number passed to it so the array is sorted in ascending order.
Example 2:
Input: arr = [{"x": 1}, {"x": 0}, {"x": -1}], fn = (d) => d.x
Output: [{"x": -1}, {"x": 0}, {"x": 1}]
Explanation: fn returns the value for the "x" key. So the array is sorted based on that value.
Example 3:
Input: arr = [[3, 4], [5, 2], [10, 1]], fn = (x) => x[1] Output: [[10, 1], [5, 2], [3, 4]] Explanation: arr is sorted in ascending order by number at index=1.
Constraints:
arr is a valid JSON arrayfn is a function that returns a number1 <= arr.length <= 5 * 105Problem Overview: You receive an array and a function fn. The task is to sort the array based on the value returned by applying fn to each element. Instead of comparing elements directly, you compare the computed keys produced by the function.
Approach 1: Using Built-in Sort with Key Function (Time: O(n log n), Space: O(1) to O(n))
The most direct solution relies on the language’s built-in sorting function. For each comparison, the algorithm applies fn(x) and fn(y) and orders the elements based on the returned values. Languages like Python provide a native key parameter, while JavaScript, Java, C++, and C# typically use a custom comparator that evaluates the function results during sorting.
The key idea is that the sorting algorithm handles ordering while your function defines the comparison rule. Internally, the algorithm performs O(n log n) comparisons, and each comparison may call the function. This makes the approach concise and easy to implement. For most interview scenarios and production code, this is the expected solution because it leverages optimized library sorting implementations.
This approach fits naturally into problems involving sorting and arrays, where you need to control ordering with a computed property.
Approach 2: Custom Sorting via a Map of Computed Keys (Time: O(n log n), Space: O(n))
Another option is to compute the key for every element once before sorting. Iterate through the array and store pairs like (fn(value), value) in a temporary structure such as a list or map. After that, sort the pairs using the precomputed key and extract the values in sorted order.
The key insight is avoiding repeated calls to fn. In some environments the sorting algorithm may evaluate the comparator many times, which can lead to redundant function executions. Precomputing the keys guarantees each element’s key is calculated exactly once. This pattern is sometimes called the “decorate-sort-undecorate” technique and commonly appears in custom comparator problems and hash map-based preprocessing.
The tradeoff is extra memory for storing the intermediate pairs. Time complexity remains O(n log n) because the array still needs to be sorted, but the function computation cost drops to O(n).
Recommended for interviews: The built-in sort with a key or comparator is what interviewers usually expect. It shows you understand how to customize sorting logic without reinventing the algorithm. Mentioning the precomputed-key optimization demonstrates deeper knowledge of how sorting repeatedly calls comparators and how to reduce redundant work.
This approach utilizes the built-in sorting functionality available in most programming languages, which allows for custom sorting based on a key extracted from each element. The function fn is used to transform each element to its sorting key during the sort operation.
This solution makes use of Python's sorted() function, which accepts a key parameter. The key parameter is provided with the function fn, such that each element is processed through this function to determine the sorting order.
Python
JavaScript
Java
C++
C#
Time Complexity: O(n log n), where n is the length of the array, due to the sort operation.
Space Complexity: O(n), as sorted() creates a new list.
This approach involves first creating a map of the computed keys from fn for all the elements in the array. These keys are then used to guide the sorting of the original array.
key_map stores the result of applying fn to each element. The array is sorted based on look-up from this dictionary during the sorting phase, providing a precomputed sort key per element.
Python
JavaScript
Time Complexity: O(n log n), owing to the sort operation.
Space Complexity: O(n), due to the additional storage in the form of key_map.
TypeScript
| Approach | Complexity |
|---|---|
| Using Built-in Sort with Key Function | Time Complexity: O(n log n), where n is the length of the array, due to the sort operation. |
| Using Custom Sorting via a Map of Computed Keys | Time Complexity: O(n log n), owing to the sort operation. |
| Default Approach | — |
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Built-in Sort with Key/Comparator | O(n log n) | O(1) to O(n) | Default solution in most languages; concise and uses optimized library sorting |
| Precompute Keys (Decorate-Sort-Undecorate) | O(n log n) | O(n) | When the key function is expensive and you want to avoid repeated evaluations |
Sort By | Leetcode 2724 | JSON | 30 Days of JavaScript #javascript #leetcode • Learn With Chirag • 1,577 views views
Watch 9 more video solutions →Practice Sort By with our built-in code editor and test cases.
Practice on FleetCodePractice this problem
Open in Editor