Given an array of integers arr
, replace each element with its rank.
The rank represents how large the element is. The rank has the following rules:
Example 1:
Input: arr = [40,10,20,30] Output: [4,1,2,3] Explanation: 40 is the largest element. 10 is the smallest. 20 is the second smallest. 30 is the third smallest.
Example 2:
Input: arr = [100,100,100] Output: [1,1,1] Explanation: Same elements share the same rank.
Example 3:
Input: arr = [37,12,28,9,100,56,80,5,12] Output: [5,3,4,2,8,6,7,1,3]
Constraints:
0 <= arr.length <= 105
-109 <= arr[i] <= 109
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 problem asks us to assign a rank to each number in a list, where the smallest number gets rank 1, the next smallest gets rank 2, and so on. The brute force way is to check every possible rank assignment and see if it satisfies the rules.
Here's how the algorithm would work step-by-step:
def rank_transform_brute_force(array):
original_array = list(array)
array_length = len(array)
ranks = [0] * array_length
def is_valid_rank_assignment(current_ranks):
for i in range(array_length):
for j in range(array_length):
if array[i] < array[j] and current_ranks[i] > current_ranks[j]:
return False
if array[i] > array[j] and current_ranks[i] < current_ranks[j]:
return False
return True
def find_rank_assignment(index):
if index == array_length:
if is_valid_rank_assignment(ranks):
return True
else:
return False
for rank in range(1, array_length + 1):
ranks[index] = rank
if find_rank_assignment(index + 1):
return True
return False
find_rank_assignment(0)
# Map original values to assigned ranks
value_to_rank = {}
for i in range(array_length):
value_to_rank[original_array[i]] = ranks[i]
sorted_values = sorted(list(set(original_array)))
rank_map = {value: i + 1 for i, value in enumerate(sorted_values)}
#Assign a rank based on the relative order of the values
result = [rank_map[value] for value in original_array]
return result
To assign ranks to elements in an array, we want to give smaller elements smaller ranks and larger elements larger ranks. The efficient approach involves sorting to understand the relative order and then mapping each element to its appropriate rank in a sequential order.
Here's how the algorithm would work step-by-step:
def rank_transform(array):
sorted_unique_numbers = sorted(list(set(array)))
# Assign ranks based on sorted order.
rank_map = {}
current_rank = 1
for number in sorted_unique_numbers:
rank_map[number] = current_rank
current_rank += 1
# Map elements in original array to their ranks
ranked_array = []
for number in array:
ranked_array.append(rank_map[number])
return ranked_array
Case | How to Handle |
---|---|
Empty input array | Return an empty array if the input is null or empty. |
Array with one element | Return an array containing only the rank 1. |
Array with all identical values | All elements should be ranked 1. |
Array with duplicate values scattered throughout | The same rank should be assigned to duplicate elements. |
Array with negative numbers | The ranking should still be based on the sorted order regardless of the sign. |
Array with a mix of positive, negative and zero values | The ranking should correctly reflect the order of all elements, including zero. |
Array with large input size nearing memory limits | Ensure the solution's memory usage remains within reasonable bounds (e.g., avoids unnecessary copies). |
Array with numbers close to integer limits (Integer.MAX_VALUE and Integer.MIN_VALUE) | Handle edge cases to prevent any possible Integer overflow. |