Replace each element of Array with it's corresponding rank (original) (raw)
Given an array arr[] of **n integers, convert it into its **reduced form. In the reduced form, each element is replaced by its rank. The smallest element should be replaced with **0, the second smallest with **1, and so on, until the largest element is replaced with **n - 1.
- The **relative positions of the elements in the array must remain unchanged.
- For repeating elements, the element appearing earlier in the original array must be of smaller rank than the one appearing later.
- You need to modify the array in-place and do not return anything.
**Examples:
**Input: arr[] = [10, 40, 20]
**Output: [0, 2, 1]
**Explanation: The elements in sorted order are [10, 20, 40]. Therefore, 10, 20, and 40 are assigned ranks 0, 1, and 2 respectively.**Input: arr[] = [0, 2, 1]
**Output: [0, 2, 1]
**Explanation: The array is already in reduced form.The elements 0, 1, and 2 are the smallest, second smallest, and largest elements respectively.**Input: arr[] = [1, 5, 3, 4, 3]
**Output: [0, 4, 1, 3, 2]
**Explanation: The elements of the array in sorted order are [1, 3, 3, 4, 5]. Assigning ranks from 0 to n - 1 gives 1 as rank 0, the first 3 as rank 1, the second 3 as rank 2, 4 as rank 3 and 5 as rank 4.
Table of Content
- [Naive Approach] - Using Brute Force Method - O(n^2) time and O(n) space
- [Efficient Approach] - Using Stable Sorting - O(n * log n) time and O(n) space
[Naive Approach] - Using Brute Force Method - O(n^2) time and O(n) space
The idea is to determine the rank of every element independently. For a given element, its rank is equal to the number of elements that are smaller than it. Since equal elements must receive different ranks based on their original order, we also count the equal elements that appear before the current element. The resulting count is the rank of that element.
C++ `
#include #include using namespace std;
void replaceWithRank(vector &arr){ int n = arr.size();
vector<int> res(n);
// For each value
for (int i = 0; i < n; i++) {
int rank = 0;
for (int j = 0; j < n; j++) {
// Count all elements smaller than arr[i].
if (arr[j] < arr[i]) {
rank++;
}
// For equal elements, count only those
// appearing before the current index.
else if (arr[j] == arr[i] && j < i) {
rank++;
}
}
// Rank of current element.
res[i] = rank;
}
// Replace array elements with their ranks.
arr = res;}
int main() { vector arr = {10, 40, 20};
replaceWithRank(arr);
for (int val : arr) {
cout << val << " ";
}
cout << endl;
return 0;}
Java
import java.util.Arrays;
class GfG { static void replaceWithRank(int[] arr) { int n = arr.length; int[] res = new int[n];
// For each value
for (int i = 0; i < n; i++) {
int rank = 0;
for (int j = 0; j < n; j++) {
// Count all elements smaller than arr[i]
if (arr[j] < arr[i]) {
rank++;
}
// For equal elements, count only those
// appearing before the current index
else if (arr[j] == arr[i] && j < i) {
rank++;
}
}
// Rank of current element
res[i] = rank;
}
// Replace array elements with their ranks
for (int i = 0; i < n; i++) {
arr[i] = res[i];
}
}
public static void main(String[] args) {
int[] arr = {10, 40, 20};
replaceWithRank(arr);
for (int val : arr) {
System.out.print(val + " ");
}
System.out.println();
}}
Python
def replaceWithRank(arr): n = len(arr) res = [0] * n
# For each value
for i in range(n):
rank = 0
for j in range(n):
# Count all elements smaller than arr[i]
if arr[j] < arr[i]:
rank += 1
# For equal elements, count only those
# appearing before the current index
elif arr[j] == arr[i] and j < i:
rank += 1
# Rank of current element
res[i] = rank
# Replace array elements with their ranks
for i in range(n):
arr[i] = res[i]if name == "main": arr = [10, 40, 20] replaceWithRank(arr) for val in arr: print(val, end=" ") print()
C#
using System;
class GfG { static void ReplaceWithRank(int[] arr) { int n = arr.Length; int[] res = new int[n];
// For each value
for (int i = 0; i < n; i++) {
int rank = 0;
for (int j = 0; j < n; j++) {
// Count all elements smaller than arr[i]
if (arr[j] < arr[i]) {
rank++;
}
// For equal elements, count only those
// appearing before the current index
else if (arr[j] == arr[i] && j < i) {
rank++;
}
}
// Rank of current element
res[i] = rank;
}
// Replace array elements with their ranks
for (int i = 0; i < n; i++) {
arr[i] = res[i];
}
}
static void Main() {
int[] arr = {10, 40, 20};
ReplaceWithRank(arr);
Console.WriteLine(string.Join(" ", arr));
}}
JavaScript
function replaceWithRank(arr) { const n = arr.length; const res = new Array(n);
// For each value
for (let i = 0; i < n; i++) {
let rank = 0;
for (let j = 0; j < n; j++) {
// Count all elements smaller than arr[i]
if (arr[j] < arr[i]) {
rank++;
}
// For equal elements, count only those
// appearing before the current index
else if (arr[j] === arr[i] && j < i) {
rank++;
}
}
// Rank of current element
res[i] = rank;
}
// Replace array elements with their ranks
for (let i = 0; i < n; i++) {
arr[i] = res[i];
}}
const arr = [10, 40, 20]; replaceWithRank(arr); console.log(arr.join(" "));
`
[Efficient Approach] - Using Stable Sorting - O(n * log n) time and O(n) space
The idea is to first store each element along with its original index as a pair (value, index). Then, we perform a stable sort based on the values. After sorting, the position of each pair in the sorted array represents its rank. Finally, using the stored indices, we place these ranks back into their original positions in the array. Stable sorting ensures that equal elements retain their relative order, so an earlier occurrence receives a smaller rank than a later occurrence.
For the array arr[] = [1, 5, 3, 4, 3]
**Step 1: Convert each element into a pair (value, index): [(1, 0), (5, 1), (3, 2), (4, 3), (3, 4)]
**Step 2: Perform a stable sort based on the values: [(1, 0), (3, 2), (3, 4), (4, 3), (5, 1)]
**Step 3: Assign ranks according to the position in the sorted array:
**Step 3: Assign ranks, We start rank from 1:
- (1, 0) -> rank 0
- (3, 2) -> rank 1
- (3, 4) -> rank 2
- (4, 3) -> rank 3
- (5, 1) -> rank 4
**Step 4: Place the ranks back using the original indices:
- index 0 -> 0
- index 1 -> 4
- index 2 -> 1
- index 3 -> 3
- index 4 -> 2
**Step 5: The final reduced form of the array is: [0, 4, 1, 3, 2]
C++ `
#include #include using namespace std;
void replaceWithRank(vector& arr) { int n = arr.size();
// A vector of pairs. Every element of
// pair contains array element and its
// index
vector<pair<int, int>> v;
// Put all elements and their index in
// the vector
for (int i = 0; i < n; i++)
v.emplace_back(arr[i], i);
// Sort the vector
sort(v.begin(), v.end());
// Put indexes of modified vector in arr[]
for (int i = 0; i < n; i++)
arr[v[i].second] = i;}
int main() { vector arr = {10, 40, 20};
replaceWithRank(arr);
for (int val : arr) {
cout << val << " ";
}
return 0;}
Java
import java.util.Arrays;
class GfG { static void replaceWithRank(int[] arr) { int n = arr.length;
// A 2D array of pairs. Every element
// contains array element and its index
int[][] v = new int[n][2];
// Put all elements and their index in the array
for (int i = 0; i < n; i++) {
v[i][0] = arr[i];
v[i][1] = i;
}
// Sort by value. For equal values, sort by
// original index so earlier occurrences
// get smaller ranks.
Arrays.sort(v, (a, b) -> {
if (a[0] != b[0]) {
return Integer.compare(a[0], b[0]);
}
return Integer.compare(a[1], b[1]);
});
// Put indexes of modified array in arr[]
for (int i = 0; i < n; i++)
arr[v[i][1]] = i;
}
public static void main(String[] args) {
int[] arr = {10, 40, 20};
replaceWithRank(arr);
for (int val : arr) {
System.out.print(val + " ");
}
System.out.println();
}}
Python
def replaceWithRank(arr): n = len(arr)
# A list of pairs. Every element of
# pair contains array element and its index
v = []
# Put all elements and their index in the list
for i in range(n):
v.append((arr[i], i))
# Stable sort by value. For equal values,
# the original order is preserved.
v.sort()
# Put indexes of modified list in arr[]
for i in range(n):
arr[v[i][1]] = iif name == "main": arr = [10, 40, 20] replaceWithRank(arr) for val in arr: print(val, end=" ") print()
C#
using System;
class GFG { static void replaceWithRank(int[] arr) { int n = arr.Length;
// A 2D array of pairs. Every element
// contains array element and its index.
int[][] v = new int[n][];
// Put all elements and their index in the array.
for (int i = 0; i < n; i++)
v[i] = new int[] { arr[i], i };
// Sort by value. For equal values, sort by
// original index so earlier occurrences
// get smaller ranks.
Array.Sort(v, (a, b) => {
int cmp = a[0].CompareTo(b[0]);
if (cmp != 0) return cmp;
return a[1].CompareTo(b[1]);
});
// Put ranks back into their original positions.
for (int i = 0; i < n; i++)
arr[v[i][1]] = i;
}
static void Main() {
int[] arr = { 10, 40, 20 };
replaceWithRank(arr);
foreach (int val in arr)
Console.Write(val + " ");
Console.WriteLine();
}}
JavaScript
function replaceWithRank(arr) { const n = arr.length;
// An array of pairs. Every element of
// pair contains array element and its index
const v = [];
// Put all elements and their index in the array
for (let i = 0; i < n; i++)
v.push([arr[i], i]);
// Sort by value. For equal values, sort by
// original index so earlier occurrences
// get smaller ranks.
v.sort((a, b) => {
if (a[0] !== b[0]) return a[0] - b[0];
return a[1] - b[1];
});
// Put indexes of modified array in arr[]
for (let i = 0; i < n; i++)
arr[v[i][1]] = i;}
// Driver code const arr = [10, 40, 20]; replaceWithRank(arr); arr.forEach(val => process.stdout.write(val + " ")); console.log();
`