Rank Transform of an Array

easy hash map sorting

Problem

Given an array of integers arr, replace every element with its rank and return the result. Ranks start at 1: the smallest value gets rank 1, larger values get larger ranks, and equal values must always receive the same rank.

The recipe: sort a copy of the array, drop duplicates, record each distinct value's 1-based position in a hash map, then walk the original array swapping every value for its stored rank.

Inputarr = [37,12,28,9,100,56,80,5,12]
Output[5,3,4,2,8,6,7,1,3]
Sorted distinct values are [5,9,12,28,37,56,80,100]: 5 is the smallest so it gets rank 1, 100 the largest gets rank 8, and both copies of 12 share rank 3.

def array_rank_transform(arr):
    sorted_unique = sorted(set(arr))
    ranks = {}
    for i, v in enumerate(sorted_unique):
        ranks[v] = i + 1
    return [ranks[v] for v in arr]
function arrayRankTransform(arr) {
  const sortedUnique = [...new Set(arr)].sort((a, b) => a - b);
  const ranks = new Map();
  sortedUnique.forEach((v, i) => ranks.set(v, i + 1));
  return arr.map(v => ranks.get(v));
}
int[] arrayRankTransform(int[] arr) {
    int[] sorted = arr.clone();
    Arrays.sort(sorted);
    Map<Integer, Integer> ranks = new HashMap<>();
    for (int v : sorted) {
        ranks.putIfAbsent(v, ranks.size() + 1);
    }
    int[] ans = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        ans[i] = ranks.get(arr[i]);
    }
    return ans;
}
vector<int> arrayRankTransform(vector<int>& arr) {
    vector<int> sorted(arr);
    sort(sorted.begin(), sorted.end());
    unordered_map<int, int> ranks;
    for (int v : sorted) {
        int r = ranks.size() + 1;
        if (!ranks.count(v)) ranks[v] = r;
    }
    vector<int> ans;
    for (int v : arr) ans.push_back(ranks[v]);
    return ans;
}
Time: O(n log n) Space: O(n)