Given an integer array arr[], that may contain duplicate elements and an index k (0-based), find the final position (0-based) of the element at index k after applying a stable sort on the array.
Note: In a stable sort, elements with equal values retain their relative order from the original array.
Examples :
Input: arr[] = [3, 4, 3, 5, 2, 3, 4, 3, 1, 5], k = 5
Output: 4
Explanation: The element at index 5 is 3. There are 2 elements smaller than 3, so the group of 3s starts at position 2. Among all occurrences of 3 (at indices 0, 2, 5, 7), index 5 is the 3rd one (0-based rank 2). Final position = 2 + 2 = 4.Input: arr[]= [3, 4, 3, 5, 2, 3, 4, 3, 1, 5], k = 2
Output: 3
Explanation: The element at index 2 is 3. There are 2 elements smaller than 3, so the group of 3s starts at position 2. Among all occurrences of 3 (at indices 0, 2, 5, 7), index 2 is the 2nd one (0-based rank 1). Final position = 2 + 1 = 3.
Table of Content
[Naive Approach] Stable Sort with Original Indices - O(n log n) Time and O(n) Space
The idea is to store every element along with its original index, perform a stable sort on the array, and then find the new position of the element that originally existed at index k.
Working of Approach:
- Store each element as (value, original index).
- Perform a stable sort based on the values.
- Stability ensures duplicate elements keep their original relative order.
- Traverse the sorted array and return the position whose original index is k.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
// Function to find the final position after stable sorting
int sortedIndex(vector<int> &arr, int k)
{
vector<pair<int, int>> temp;
// Store value with its original index
for (int i = 0; i < arr.size(); i++)
temp.push_back({arr[i], i});
// Stable sort according to value
stable_sort(temp.begin(), temp.end());
// Find the element having original index k
for (int i = 0; i < temp.size(); i++)
{
if (temp[i].second == k)
return i;
}
return -1;
}
int main()
{
vector<int> arr = {3, 4, 3, 5, 2, 3, 4, 3, 1, 5};
int k = 2;
cout << sortedIndex(arr, k);
return 0;
}
import java.util.ArrayList;
import java.util.Collections;
class Pair {
int value;
int index;
Pair(int value, int index)
{
this.value = value;
this.index = index;
}
}
public class GFG {
// Function to find the final position after stable
// sorting
static int sortedIndex(int[] arr, int k)
{
ArrayList<Pair> temp = new ArrayList<>();
// Store value with its original index
for (int i = 0; i < arr.length; i++)
temp.add(new Pair(arr[i], i));
// Stable sort according to value
Collections.sort(
temp,
(a, b) -> Integer.compare(a.value, b.value));
// Find the element having original index k
for (int i = 0; i < temp.size(); i++) {
if (temp.get(i).index == k)
return i;
}
return -1;
}
public static void main(String[] args)
{
int[] arr = { 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 };
int k = 2;
System.out.println(sortedIndex(arr, k));
}
}
def sortedIndex(arr, k):
# Store value with its original index
temp = [(arr[i], i) for i in range(len(arr))]
# Stable sort according to value
temp.sort(key=lambda x: x[0])
# Find the element having original index k
for i in range(len(temp)):
if temp[i][1] == k:
return i
return -1
if __name__ == "__main__":
arr = [3, 4, 3, 5, 2, 3, 4, 3, 1, 5]
k = 2
print(sortedIndex(arr, k))
using System;
using System.Collections.Generic;
class Pair {
public int value;
public int index;
public Pair(int value, int index)
{
this.value = value;
this.index = index;
}
}
class GFG {
// Function to find the final position after stable
// sorting
static int sortedIndex(int[] arr, int k)
{
List<Pair> temp = new List<Pair>();
// Store value with its original index
for (int i = 0; i < arr.Length; i++)
temp.Add(new Pair(arr[i], i));
// Sort by value, then by original index
temp.Sort(delegate(Pair a, Pair b) {
if (a.value != b.value)
return a.value.CompareTo(b.value);
return a.index.CompareTo(b.index);
});
// Find the element having original index k
for (int i = 0; i < temp.Count; i++) {
if (temp[i].index == k)
return i;
}
return -1;
}
static void Main()
{
int[] arr = { 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 };
int k = 2;
Console.WriteLine(sortedIndex(arr, k));
}
}
function sortedIndex(arr, k)
{
let temp = [];
// Store value with its original index
for (let i = 0; i < arr.length; i++)
temp.push([ arr[i], i ]);
// Stable sort according to value
temp.sort((a, b) => a[0] - b[0]);
// Find the element having original index k
for (let i = 0; i < temp.length; i++) {
if (temp[i][1] == k)
return i;
}
return -1;
}
// Driver Code
let arr = [ 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 ];
let k = 2;
console.log(sortedIndex(arr, k));
Output
3
[Expected Approach] Count Smaller and Previous Equal Elements - O(n) Time and O(1) Space
As position of an element in a sorted array is decided by only smaller or equal on left, we count these for k. The count directly gives us the final position after a stable sort.
Working of Approach:
- Traverse the array once.
- Count all elements smaller than arr[k].
- Count all occurrences of arr[k] that appear before index k.
- The sum of these two counts gives the final position after stable sorting.
Let us understand with an example:
Input: arr[]= [3, 4, 3, 5, 2, 3, 4, 3, 1, 5], k = 2
- The element at index k is 3, so we find its position after a stable sort.
- Count all elements smaller than 3 (2 and 1), giving 2 elements before it in the sorted array.
- Count all occurrences of 3 before index k (arr[0]), giving 1 previous duplicate.
- Stable sorting keeps duplicate elements in their original order, so this previous 3 stays before the current one.
- Final position = 2 + 1 = 3.
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
int sortedIndex(vector<int> &arr, int k)
{
int res = 0;
int n = arr.size();
for (int i = 0; i < n; i++)
{
// elements smaller than arr[k] would appear before it in sorted order
if (arr[i] < arr[k])
res++;
// for duplicates, only count those appearing before index k
// to maintain stable relative ordering
if (arr[i] == arr[k] && i < k)
res++;
}
// res is the 0-based index of arr[k] in the sorted array
return res;
}
int main()
{
vector<int> arr = {3, 4, 3, 5, 2, 3, 4, 3, 1, 5};
int k = 2;
cout << sortedIndex(arr, k);
return 0;
}
import java.util.Arrays;
public class GFG {
public static int sortedIndex(int[] arr, int k)
{
int res = 0;
int n = arr.length;
for (int i = 0; i < n; i++) {
// elements smaller than arr[k] would appear
// before it in sorted order
if (arr[i] < arr[k])
res++;
// for duplicates, only count those appearing
// before index k to maintain stable relative
// ordering
if (arr[i] == arr[k] && i < k)
res++;
}
// res is the 0-based index of arr[k] in the sorted
// array
return res;
}
public static void main(String[] args)
{
int[] arr = { 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 };
int k = 2;
System.out.println(sortedIndex(arr, k));
}
}
def sortedIndex(arr, k):
res = 0
n = len(arr)
for i in range(n):
# elements smaller than arr[k] would appear before it in sorted order
if arr[i] < arr[k]:
res += 1
# for duplicates, only count those appearing before index k
# to maintain stable relative ordering
if arr[i] == arr[k] and i < k:
res += 1
# res is the 0-based index of arr[k] in the sorted array
return res
if __name__ == '__main__':
arr = [3, 4, 3, 5, 2, 3, 4, 3, 1, 5]
k = 2
print(sortedIndex(arr, k))
using System;
public class GFG {
public static int sortedIndex(int[] arr, int k)
{
int res = 0;
int n = arr.Length;
for (int i = 0; i < n; i++) {
// elements smaller than arr[k] would appear
// before it in sorted order
if (arr[i] < arr[k])
res++;
// for duplicates, only count those appearing
// before index k to maintain stable relative
// ordering
if (arr[i] == arr[k] && i < k)
res++;
}
// res is the 0-based index of arr[k] in the sorted
// array
return res;
}
public static void Main()
{
int[] arr = { 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 };
int k = 2;
Console.WriteLine(sortedIndex(arr, k));
}
}
function sortedIndex(arr, k)
{
let res = 0;
let n = arr.length;
for (let i = 0; i < n; i++) {
// elements smaller than arr[k] would appear before
// it in sorted order
if (arr[i] < arr[k])
res++;
// for duplicates, only count those appearing before
// index k to maintain stable relative ordering
if (arr[i] === arr[k] && i < k)
res++;
}
// res is the 0-based index of arr[k] in the sorted
// array
return res;
}
// Driver Code
let arr = [ 3, 4, 3, 5, 2, 3, 4, 3, 1, 5 ];
let k = 2;
console.log(sortedIndex(arr, k));
Output
3