# Sort elements by frequency | Set 1

Print the elements of an array in the decreasing frequency if 2 numbers have same frequency then print the one which came first.

Examples:

```Input:  arr[] = {2, 5, 2, 8, 5, 6, 8, 8}
Output: arr[] = {8, 8, 8, 2, 2, 5, 5, 6}

Input: arr[] = {2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8}
Output: arr[] = {8, 8, 8, 2, 2, 5, 5, 6, -1, 9999999}
```

METHOD 1 (Use Sorting)

```  1) Use a sorting algorithm to sort the elements O(nlogn)
2) Scan the sorted array and construct a 2D array of element and count O(n).
3) Sort the 2D array according to count O(nlogn).
```

Example:

```  Input 2 5 2 8 5 6 8 8

After sorting we get
2 2 5 5 6 8 8 8

Now construct the 2D array as
2, 2
5, 2
6, 1
8, 3

Sort by count
8, 3
2, 2
5, 2
6, 1
```

How to maintain order of elements if frequency is same?
The above approach doesn’t make sure order of elements if frequency is same. To handle this, we should use indexes in step 3, if two counts are same then we should first process(or print) the element with lower index. In step 1, we should store the indexes instead of elements.

```  Input 5  2  2  8  5  6  8  8

After sorting we get
Element 2 2 5 5 6 8 8 8
Index   1 2 0 4 5 3 6 7

Now construct the 2D array as
Index, Count
1,      2
0,      2
5,      1
3,      3

Sort by count (consider indexes in case of tie)
3, 3
0, 2
1, 2
5, 1

Print the elements using indexes in the above 2D array.
```

Below is C++ implementation of above approach.

```// Sort elements by frequency. If two elements have same
// count, then put the elements that appears first
#include<bits/stdc++.h>
using namespace std;

// Used for sorting
struct ele
{
int count, index, val;
};

// Used for sorting by value
bool mycomp(struct ele a, struct ele b) {
return (a.val < b.val);
}

// Used for sorting by frequency. And if frequency is same,
// then by appearance
bool mycomp2(struct ele a, struct ele b) {
if (a.count != b.count) return (a.count < b.count);
else return a.index > b.index;
}

void sortByFrequency(int arr[], int n)
{
struct ele element[n];
for (int i = 0; i < n; i++)
{
element[i].index = i;    /* Fill Indexes */
element[i].count = 0;    /* Initialize counts as 0 */
element[i].val = arr[i]; /* Fill values in structure
elements */
}

/* Sort the structure elements according to value,
we used stable sort so relative order is maintained. */
stable_sort(element, element+n, mycomp);

/* initialize count of first element as 1 */
element[0].count = 1;

/* Count occurrences of remaining elements */
for (int i = 1; i < n; i++)
{
if (element[i].val == element[i-1].val)
{
element[i].count += element[i-1].count+1;

/* Set count of previous element as -1 , we are
doing this because we'll again sort on the
basis of counts (if counts are equal than on
the basis of index)*/
element[i-1].count = -1;

/* Retain the first index (Remember first index
is always present in the first duplicate we
used stable sort. */
element[i].index = element[i-1].index;
}

/* Else If previous element is not equal to current
so set the count to 1 */
else element[i].count = 1;
}

/* Now we have counts and first index for each element so now
sort on the basis of count and in case of tie use index
to sort.*/
stable_sort(element, element+n, mycomp2);
for (int i = n-1, index=0; i >= 0; i--)
if (element[i].count != -1)
for (int j=0; j<element[i].count; j++)
arr[index++] = element[i].val;
}

// Driver program
int main()
{
int arr[] = {2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8};
int n = sizeof(arr)/sizeof(arr[0]);

sortByFrequency(arr, n);

for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
```

Output:

`8 8 8 2 2 5 5 6 -1 9999999 `

Thanks to Gaurav Ahirwar for providing above implementation.

METHOD 2(Use BST and Sorting)
1. Insert elements in BST one by one and if an element is already present then increment the count of the node. Node of the Binary Search Tree (used in this approach) will be as follows.

```struct tree
{
int element;
int first_index /*To handle ties in counts*/
int count;
}BST;
```

2.Store the first indexes and corresponding counts of BST in a 2D array.
3 Sort the 2D array according to counts (and use indexes in case of tie).

Time Complexity: O(nlogn) if a Self Balancing Binary Search Tree is used. This is implemented in Set 2.

METHOD 3(Use Hashing and Sorting)
Using a hashing mechanism, we can store the elements (also first index) and their counts in a hash. Finally, sort the hash elements according to their counts.

• ANA

how to sort 2-d array with index and value such that if two values is same then the value with lower index is printed first ?
in nlogn

• zzer

#include

#include

#include

#include

#include

#include

using namespace std;

class Elem

{

public:

Elem(){}

Elem(int v,int c,int i):value(v),count(c),index(i){}

int value;

int count;

int index;// lowest index

bool operator other.count) || (count==other.count && index < other.index);

}

};

void sort_by_frequency(int arr[],int n)

{

if(n <= 0)

return;

map maps;

for(int i = 0; i 0 )

{

maps[arr[i]].count++;

}

else

maps.insert(make_pair(arr[i],Elem(arr[i],1,i)));

}

vector vec;

for(map::iterator it = maps.begin(); it != maps.end(); it++)

vec.push_back(it->second);

sort(vec.begin(),vec.end());

for(vector::iterator it = vec.begin(); it != vec.end(); it++)

{

while(it->count– > 0)

cout <value << " ";

}

cout << endl;

}

int main()

{

int arr[] = {2,5,2,8,5,6,8,8};

for(int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)

cout << arr[i] << " ";

cout << endl << "——————————" << endl;

sort_by_frequency(arr,sizeof(arr)/sizeof(arr[0]));

return 0;

}

• Mari

In third Solution, Step 2, Since the frequency of any number lies between 1 to n, we can use Counting Sort. Thus over all running time of this solution will be O(n)(Hash table operations + counting sort).

• Meenal

I tried to modify merge sort for storing original indexes after modification it is not sorting properly.. I am not able to find where I have gone wrong Please help me find the issue..

http://ideone.com/ORQLql

• Coder011

You havent mentioned what does the ordered pair {x,y} , in your array ‘a’ signify? I assumed the value y as array value and, x as index. But even going by that logic where have you stored the frequency?

• Meenal

Hi, your assumption of {x,y} is correct.
This part of code is written just for sorting the array and storing previous indexes corresponding to elements in a[i][1] only. As it is not sorting correctly itself. I could not proceed.

I am not able to get why making it a 2D array affected it, as with 1D array having only values this merge sort program works perfectly fine.

• Coder011

In the stdout of the program (taken from Ideone):
553456789102
Array after sorting:

Index after sorting:
9 1 2 3 4 5 6 7 8 0
Array after sorting:
2 3 4 5 6 7 8 9 10 55

I suppose, the array has been sorted. Have you tried it on any other test cases as well? Otherwise the code looks fine to me.

• Meenal

Thanks for checking it..
I was facing problem with same test case, there was one issue in my code in if loop instead of (L[i][1]
< R[j][1]) i used (L[i] < R[j]) by mistake… Gues you have fixed it in your code…
Thanks

• Guest
• jedi

#include

//given an array, first sort in nlogn time using merge sort

mergesort(int A[][2],int left,int right)

{

if(left>=right)

return A[left][1];

int mid=(left+right)/2;

mergesort(A,left,mid);

mergesort(A,mid+1,right);

merge(A,left,mid,right);

}

merge(int A[][2],int left,int mid,int right)

{

int n=mid-left+1;

int m=right-mid;

int i;

int B[n][2],C[m][2];

for(i=0;i<n;i++)

{

B[i][1]=A[left+i][1];

B[i][0]=A[left+i][0];

}

for(i=0;i<m;i++)

{

C[i][1]=A[mid+1+i][1];

C[i][0]=A[mid+1+i][0];

}

i=left;

int j,k;

j=0;

k=0;

while((j<mid-left+1)&&(k<right-mid))

{

if(B[j][1]<C[k][1])

{

A[i][1]=B[j][1];

A[i][0]=B[j][0];

j++;

i++;

}

else if(B[j][1]==C[k][1])

{

if(B[j][0]=mid-left+1)

{

while(k<right-mid)

{A[i][1]=C[k][1];

A[i][0]=C[k][0];

k++;

i++;}

}

else

{

while(j<mid-left+1)

{A[i][1]=B[j][1];

A[i][0]=B[j][0];

j++;

i++;}

}

}

//calc frequency of each using variables count,store as follows….copy the initial index values of A in 1st column of B i.e. B[i][0]

//remember to import a copy of the original unsorted array to pass to print function

checkingFreq(int A[][2],int C[][2],int n)

{

//printing the sorted array

printA(A,n);

printf("n");

int i,j,count,store;

j=0;

count=1;

int B[10][2];

store=0;

for(i=1;i<=n;i++)

{

//checking the repetitions

if(A[i][1]==A[i-1][1])

count++;

//increment in case of repetition

else

{

//store the first occuring index of a set of repeating numbers into B to break ties in sorting

B[j][0]=A[store][0];

//counting the number of repetitions of a particular number

B[j][1]=count;

//reset count

count=1;

//move to index of next number

store=i;

j++;

}

}

printA(B,j);

printf("n");

//sorting by frequency, size of array=j

mergesort(B,0,j-1);

//F Y R

printA(B,j);

printf("n");

print(C,B,j);

}

print(int A[][2],int B[][2],int n)

{

int i;

for(i=0;i<n;i++)

{

printf("%d %dn",A[(B[i][0])][1],B[i][1]);

}

}

printA(int A[][2],int n)

{

int i;

for(i=0;i<n;i++)

{

printf("%d %dn",A[i][0],A[i][1]);

}

}

main()

{

int n=6,i,j;

int A[n][2],B[n][2];

for(i=0;i<n;i++)

{A[i][0]=i;}

A[0][1]=3;

A[1][1]=3;

A[2][1]=5;

A[3][1]=2;

A[4][1]=3;

A[5][1]=1;

//copying A into B

for(j=0;j<n;j++)

{

B[j][0]=A[j][0];

B[j][1]=A[j][1];

}

printf("n");

mergesort(A,0,5);

checkingFreq(A,B,6);

}

• jedi

• Suryabhan Singh

How i m going to use hashing if range is unknown ????

• alien

You need not use the same element to store in hashing array. You can use some hash function on each element and put them into a specific range and then put into hash table

• alien

it would be in o(n) time but the question is you need to change the key for hash table

• hbandi

see this

``` ```

import java.util.*;

public class NumberCount {

public static void main(String[] args) {
NumberCount nc = new NumberCount();
int[] array = { 2, 5, 2, 8, 5, 6, 8, 8 };
System.out.println("Map is :: " + nc.getMapForCounts(array));
}

private Map sortedMap(Map map) {
List<Integer> list = new ArrayList(map.entrySet());
Collections.sort(list, new Comparator() {
public int compare(Object one, Object two) {
return ((Comparable) ((Map.Entry) (two)).getValue())
.compareTo(((Map.Entry) (one)).getValue());
}
});
Map<Integer, Integer> sortedMap = new LinkedHashMap<Integer, Integer>();
for (Iterator it = list.iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();

sortedMap.put((Integer) entry.getKey(), (Integer) entry.getValue());
}
return sortedMap;
}

public Map<Integer, Integer> getMapForCounts(int[] array) {

Map<Integer, Integer> map = new HashMap<Integer, Integer>();

for (int i = 0; i < array.length; i++) {
if (map.containsKey(array[i])) {
map.put(array[i], map.get(array[i]).intValue() + 1);
} else {
map.put(array[i], 1);
}
}
return sortedMap(map);
}

}

``` ```
• akshat gupta

GeeksforGeeks?-in Method 2:
BST can have height Ranging from lg10 – 10,
so T(n)=O(10.n) or O(n),
not O(n lgn)

• Guest

@GeeksforGeeks, We can using the idea similar to counting sort and solve this problem in O(n) time and O(n) space. Although we have random input, but the frequency of any element inside the input data set will be between 1 to n, and we can exploit this property.

• Ankit Malhotra

O(n^2) code follows. First build a linked list with frequency and lowest index. Then use the linked list to build a BST. The case of equal frequencies is handled easily here as the liked list anyway returns lower indices first.

``` ```
#include <iostream>
#define MAXCOUNT 1000
using namespace::std;
typedef int element;
typedef int counter;

struct datanode
{
element data;
counter frequency;
counter index;
datanode * next;
datanode (element data, counter index)
{
this->data = data;
this->frequency = 1;
this->index = index;
this->next = NULL;
}
};

typedef datanode * lptr;

lptr frequency (element * term, counter count)
{
if (!count) return NULL;
lptr start = new datanode(term[0], 0), p;
for (counter i = 1; i < count; i++)
{
for(p = start; p && p->next && p->data != term[i]; p = p->next);
if (p && p->data == term[i]) p->frequency++;
else p->next = new datanode(term[i], i);
}
return start;
}

void destroy (lptr p)
{
lptr k;
while(p)
{
k = p;
p = p->next;
delete k;
}
}

struct frequencynode
{
counter frequency;
counter index;
frequencynode * left;
frequencynode * right;
frequencynode (counter frequency, counter index)
{
this->frequency = frequency;
this->index = index;
this->left = this-> right = NULL;
}
};

typedef frequencynode * ptr;

ptr sortfrequencyindex (lptr datalist)
{
if (!datalist) return NULL;
ptr start = new frequencynode (datalist->frequency, datalist->index), p, k, last;
for (datalist = datalist->next; datalist; datalist = datalist->next)
{
for(p = start, last = NULL; p != last;)
{
last = p;
if (datalist->frequency <= p->frequency) p = p->left ? p->left : p;
else p = p->right ? p->right : p;
}
k = new frequencynode (datalist->frequency, datalist->index);
if (datalist->frequency <= p->frequency) p->left = k;
else p-> right = k;
}
return start;
}

// Count must be passed set to 0
void frequencyorder (ptr p, element * term, element * reordered, counter &count)
{
if (!p) return;
frequencyorder (p -> right, term, reordered, count);
for(int i = 0; i < p->frequency; reordered[count + i++] = term[p->index]);
count += p->frequency;
frequencyorder (p -> left, term, reordered, count);
}

int main()
{
element term[] = {-10, 0, -30, 0, -30, 0, -36, -10, -25}, reordered[MAXCOUNT];
counter count = sizeof(term)/sizeof(element), index[MAXCOUNT] = {-1};
cout << "Original Array ..." << endl;
for (counter i = 0; i < count; i++) cout << term[i] << ' ';
cout << endl;
lptr list = frequency (term, count);
ptr k = sortfrequencyindex (list);
destroy (list);
frequencyorder (k, term, reordered, count = 0); // Pass count reference set to 0
cout << "Frequency Sorted on Index ..." << endl;
for (counter i = 0; i < count; i++) cout << reordered[i] << ' ';
cout << endl;
return 0;
}
``` ```
• Ankit Malhotra

Added code to destory binary tree.

``` ```
void destroy (ptr p)
{
if (!p) return;
ptr k = p;
destroy (p->left);
destroy (p->right);
delete k;
}

int main()
{
element term[] = {-10, 0, -30, 0, -30, 0, -36, -10, -25}, reordered[MAXCOUNT];
counter count = sizeof(term)/sizeof(element), index[MAXCOUNT] = {-1};
cout << "Original Array ..." << endl;
for (counter i = 0; i < count; i++) cout << term[i] << ' ';
cout << endl;
lptr list = frequency (term, count);
ptr k = sortfrequencyindex (list);
destroy (list);
frequencyorder (k, term, reordered, count = 0); // Pass count reference set to 0
destroy (k);
cout << "Frequency Sorted on Index ..." << endl;
for (counter i = 0; i < count; i++) cout << reordered[i] << ' ';
cout << endl;
return 0;
}
``` ```
• ankit

In my opinion maxHeap will be the best ds, heapify based on the count, and store count, number and index in the node. If there is a tie in the frequency, we have to just check the children of the root.

• alien

it would be iin o(nlogn). If linear time algorithm is there, we should use that only

• alien

it would be iin o(nlogn). If linear time algorithm is there, we should use that only

• algobard

Can you guys post the codes for this question? Please!

• saurabh
``` ```
It can be done by performing Counting Sort twice.
For the first time the frequency of each number is counted in another array.
For the second time, we perform counting on the frequencies with same value.
Space complexity = O(4n). Time Complexity = O(5n). So basically both space and time complexities are of the order n.

#include <stdio.h>
# define ARY_SIZE 50
//a[] is input array, d[] is output array
int sortByFreq(int a[], int d[], int len) {
int b[len], c[len], i, newLen = 0;
for(i = 0; i < len; i++) {
b[i] = 0;
c[i] = 0;
}
// Frequency of each element is stored in b[]
for(i = 0; i < len; i++)
b[a[i]]++;
// Counting for freq with same value in c[]
for(i = 0; i < len; i++)
c[b[i]]++;
// indexing for the output in array d[]
for(i = len - 2; i > 0; i--)
c[i] += c[i+1];
// d[] is finally created now
for(i = len - 1; i >= 0; i--) {
if(b[a[i]]) {
d]] - 1] = a[i];
c[b[a[i]]]--;
b[a[i]] = 0;
newLen++;
}
}
return newLen;
}

int main() {
int len = 0, n;
int a[ARY_SIZE];
printf("Enter the numbers of the array:\n");
while(scanf("%d", &n) == 1)
a[len++] = n;
int d[len];
len = sortByFreq(a, d, len);
printf("The sorted array in decreasing frequency is:\n");
for(n = 0; n < len; n++)
printf("%d  ", d[n]);
printf("\n");
}
``` ```
• Ankit Malhotra

This code gives segmentation fault on the simplest of inputs. Also has a huge design constraint in total inability to use negative numbers at all as terms are used as direct array indices.

• can’t we use array of structures instead of using bst ?

• rajcools
``` ```
//Code for method 1
//anybody who wants to test using different values please change //values in main
//MergeSort(initial2D,0,7); here 7 is sizeof array -1
//CreateArray(initial2D,8); 8 is sizeof array
//MergeSort1(initial2D,0,3); 3 is number of different values in //array -1

void swap(int &a,int &b)
{
int temp;
temp = b;
b=a;
a=temp;
}
void Merge(int arr[][3], int p, int q, int r)
{
int n1 = q-p+1;
int n2 = r-q;
int l[n1][2];
int m[n2][2];
for(int i=0;i<n1;i++)
{
l[i][0]=arr[p+i][0];
l[i][1]=arr[p+i][1];
}
for(int j=0;j<n2;j++)
{
m[j][0]=arr[q+j+1][0];
m[j][1]=arr[q+j+1][1];
}
l[n1][0]=10000;
m[n2][0]=10000;
int i=0;
int j=0;
for(int k=p;k<=r;k++)
{
if(l[i][0]<=m[j][0])
{
arr[k][0]=l[i][0];
arr[k][1]=l[i][1];
i=i+1;
}
else
{
arr[k][0]=m[j][0];
arr[k][1]=m[j][1];
j=j+1;
}
}
}

void MergeSort(int arr[][3],  int p, int r)
{
int q;
if(p<r)
{
q = (p+r)/2;
MergeSort(arr,p,q);
MergeSort(arr,q+1,r);
Merge(arr,p,q,r);
}
}
void Merge1(int arr[][3], int p, int q, int r)
{
int n1 = q-p+1;
int n2 = r-q;
int l[n1][3];
int m[n2][3];
for(int i=0;i<n1;i++)
{
l[i][2]=arr[p+i][2];
l[i][1]=arr[p+i][1];
l[i][0]=arr[p+i][0];
}
for(int j=0;j<n2;j++)
{
m[j][2]=arr[q+j+1][2];
m[j][1]=arr[q+j+1][1];
m[j][0]=arr[q+j+1][0];
}
l[n1][2]=0;
l[n1][1]=10000;
m[n2][2]=0;
l[n2][1]=10000;
int i=0;
int j=0;
for(int k=p;km[j][2])
{
arr[k][0]=l[i][0];
arr[k][1]=l[i][1];
arr[k][2]=l[i][2];
i=i+1;
}
else if(l[i][2]==m[j][2])
{
if(l[i][1]<m[j][1])
{
arr[k][0]=l[i][0];
arr[k][1]=l[i][1];
arr[k][2]=l[i][2];
i=i+1;

}
else
{
arr[k][0]=m[j][0];
arr[k][1]=m[j][1];
arr[k][2]=m[j][2];

j=j+1;

}
}
else
{
arr[k][0]=m[j][0];
arr[k][1]=m[j][1];
arr[k][2]=m[j][2];

j=j+1;
}
}
}

void MergeSort1(int arr[][3],  int p, int r)
{
int q;
if(p<r)
{
q = (p+r)/2;
MergeSort1(arr,p,q);
MergeSort1(arr,q+1,r);
Merge1(arr,p,q,r);
}
}

void CreateArray(int arr2D[][3],int size)
{
int k=0;
int count=1;
//create index
int i;
for( i =0;i<size;i++)
{
if((i!=0)&&(arr2D[i][0]==arr2D[i-1][0]))
{
count++;
continue;
}
else
{
if(i!=0)
{
//count is at 2nd column
arr2D[i-count][2] = count;

count =1;
}
}
}
arr2D[i-count][2] = count;
for(int i=0;i<8;i++)
{
printf("%d\t",arr2D[i][0]);
printf("%d\t",arr2D[i][1]);
printf("%d\t",arr2D[i][2]);
printf("\n");
}

k=0;
for(int i=0;i<size;i++)
{
if(arr2D[k][2] ==0)
{
while((arr2D[i][2] ==0)&&(i<size))
i++;
if(i==size)
break;
arr2D[k][0]=arr2D[i][0];
arr2D[k][1]=arr2D[i][1];
arr2D[k][2]=arr2D[i][2];
arr2D[i][0] = arr2D[i][1] = arr2D[i][2] =0;

}
k++;
}
}

int main()
{
int arr[8] = {5,2,2,8,5,6,8,8};
//CHECKED WITH SECOND INPUT 23,12,45,23,9,23,45,12
printf("Original array is \n");
for(int i=0;i<8;i++)
printf("%d  ",arr[i]);
printf("\n");
int initial2D[8][3];
for(int i=0;i<8;i++)
{
initial2D[i][0] = arr[i];
initial2D[i][1] = i;
initial2D[i][2] = 0;
}
MergeSort(initial2D,0,7);
CreateArray(initial2D,8);
MergeSort1(initial2D,0,3);
printf("Value\tindex\tcount\n");
for(int i=0;i<8;i++)
{
printf("%d\t",initial2D[i][0]);
printf("%d\t",initial2D[i][1]);
printf("%d\t",initial2D[i][2]);
printf("\n");
}
int i=0;
while(initial2D[i][2]!=0)
{
for(int j =0;j<initial2D[i][2];j++)
printf("%d ",initial2D[i][0]);

i++;
}

getchar();
}
``` ```
• rajcools

I have written the code for method 1.
I have created a 2-D array that stores – value, index and count
step1
1) sort this 2-D array on the basis of number
2) count the number of times value exist
3) sort on the basis of count taking index into consideration when there is a tie.
4)output the value

My implementation
1)merge sort used for this function name MergeSort O(n)
2)in 2d array calculate count for every value and store in 1st entry corresponding to that value. In subsequent entries corresponding to this value count value is zero.And then delete repetitive entries of value , only entries in which count value is non zero remain. 2d array is condensed. If there are four different values only 1st 4 entries of 2D array will be useful
This is in function create array. O(n)
3)this is accomplished again via mergesort(different from mergesort of 1st step). iin function mergesort1
4)this is done in main

• abc

A small correction:
In the first example the treap I drew at the end is wrong. It should be:

``` ```
8 (c=3, fi =4)
/
2 (c=2, fi =0)
\
5 (c=2, fi=1)
``` ```
• abc

Just thinking aloud, I somewhere feel we can use a treap here? This looks like a classic example where a treap can be used.
Say the input is:
2,5,2,5,8,8,8
o/p should be: 8,8,8,2,2,5,5

So here count will serve as priority for a treap.
So lets enter numbers.
(i am using ‘c’ for count and ‘fi’ as the first index in the brackets for a node)

``` ```
1) 2
2 (c=1, fi=0)
2) 5
2 (c=1, fi=0)
/ \
5
(c=1, fi=1)
3) enter 2. So here as its already present we increment the count
2 (c=2, fi=0)
/ \
5
(c=1, fi=1)
Whenever we increment the count (aka priority) in a treap, we do a set of rotations if the priority of the node gets bigger than it's parent.
Here that's not the case so we go ahead
4) 5:
2 (c=2, fi=0)
/ \
5
(c=2, fi=1)

Now the additional step here when the priority of the node is same as priority of the parent. we do rotation if the first index of node is smaller than parent. here that's not the case. so we go ahead

2 (c=2, fi=0)
/ \
(c=2, fi=1) 5   8 (c=3, fi =4)

when count of 8 became 2, it became same as parent's but then we didn't need rotation as the fi of 8 was greater than 2.
now when the count became 3, the count is greater than parent's so we do rotation

8 (c=3, fi =4)
/
5 (c=2, fi =1)
/
2 (c=2, fi=0)

Now just do extract max (treap is a heap on the count variable)

Another example:
5,2,8,2,5,8,8

1) 5:
5 (c=1, fi =0)
2) 2:
5 (c=1, fi =0)
/
(c=1, fi = 1)2
3) 8:

5 (c=1, fi =0)
/ \
(c=1, fi = 1)2   8 (c=1, fi = 2)

4) 2:

5 (c=1, fi =0)
/ \
(c=2, fi = 1)2   8 (c=1, fi = 2)

rotate:

2 (c=2, fi =1)
\
5 (c=1, fi =0)
\
8 (c=1, fi = 2)

5) 5:

2 (c=2, fi =1)
\
5 (c=2, fi =0)
\
8 (c=1, fi = 2)
priority same as parent's and fi less than parent's - rotate

5 (c=2, fi =0)
/ \
(c=2, fi = 1)2   8 (c=1, fi = 2)

6) 8:
5 (c=2, fi =0)
/ \
(c=2, fi = 1)2   8 (c=2, fi = 2)

7) 8:

5 (c=2, fi =0)
/ \
(c=2, fi = 1)2   8 (c=3, fi = 2)

Priority got more than parent's - rotate

8 (c=3, fi = 2)
/
5 (c=2, fi =0)
/
2 (c=2, fi = 1)

now: 8885522
``` ```
• Vamshi Krishna

In Method 1 using [index, count] approach – there is no need to sort the array to obtain the [index, count] array. Just traverse thru the input array, add new index in the if the element is new, else increment the count for the existing entry.

This can be done in O(n) time complexity, where as sorting would take O(nlogn) time.

• HI Sandeep, GeeksforGeeks

i am just about to finish the exact working solution my program time complexity is O(nlogn) & space complexity is O(n) can we do it in O(1) may b i am missing sum-thing..given suggestion….posting the solution of this problem exits me..so reply fast…what i am trying to saying is that once we get the freq.of each word,char int ..then we have to store it in some array or hashset or simple set ..so space is o(nj) ..so can we do better

Shashank

• Shashank Mani Narayan

will help just little modification needed

• Rini

In the hashing technique, if we modify it to maintain (instead of the count)a linked list of pointers to the position of the element in the array, or say the index in the array, then sorting would no longer be required. The linked list would ensure it’s stable too.

• Sam

My solution is as following and appreciate your code optimization

``` ```
public class FreqIndexPair
{
public int Freq { get; set; }
public int FirstIndex { get; set; }
}

public static int[] SortByFrequencyAndFirstOccurence(int[] array)
{
Dictionary hash = new Dictionary();
for (int i = 0; i < array.Length; i++)
{
if (!hash.ContainsKey(array[i]))
{
hash.Add(array[i], new FreqIndexPair() { FirstIndex = i, Freq = 0 });
}
hash[array[i]].Freq++;
}

FreqIndexPair[] FIArray = hash.Values.ToArray();
Array.Sort(FIArray, new MyCompare());

int[] newArray = new int[array.Length];
int counter = 0;
for (int j = 0; j < FIArray.Length; j++)
{
for (int k = 0; k < FIArray[j].Freq; k++)
{
newArray[counter] = array[FIArray[j].FirstIndex];
counter++;
}
}

for (int i = 0; i < newArray.Length; i++)
{
array[i] = newArray[i];
}

return array;
}

public class MyCompare : IComparer
{

#region IComparer Members

public int Compare(FreqIndexPair x, FreqIndexPair y)
{
if (x.Freq > y.Freq)
{
return -1;
}
else if (x.Freq  y.FirstIndex)
{
return 1;
}
else if (x.FirstIndex < y.FirstIndex)
{
return -1;
}
else
{
return 0;
}
}
}
``` ```
• Sandeep

@Sam: Thanks for sharing the code. Could you also write the algorithm used in the above implementation, please?

• Algoseekar

• rahul

@sandeep can you please post the exact working code for this problem i haven’t found its solution anywhere ..??

• GeeksforGeeks

@Algoseekar & @rahul:

We will try to add code to this post. In the mean time, you can follow following links for implementation.

• geeksforgeeks

@ankit: Thanks for reporting this case. We have modified the above methods to handle same.

• ankit

If we modify the input as: 5 2 2 8 5 6 8 8, the code should print 8 8 8 5 5 2 2 6 and not 8 8 8 2 2 5 5 6 as will be the case.

• umesh

Working solution…:)

public class RepeatedNumber {

public static void sort(int[] a)
{
HashMap map=new HashMap();

for(int i=0;i<a.length;i++)
{
if(map.containsKey(a[i]))
{
int count=map.get(a[i]);
map.put(a[i],++count);
}
else
{
map.put(a[i],1);
}
}

Set keys=map.keySet();

Iterator it=keys.iterator();
while(it.hasNext())
{
int key=(Integer) it.next();
int value=map.get(key);

Number num=new Number();
num.count=value;
num.num=key;
}
System.out.println(q.size());
Collections.sort(q);

Iterator listIterator = q.iterator();
while(listIterator.hasNext())
{
Number i=(Number) listIterator.next();
for(int k=0;knewNum.count)
return -1;
else
return 1;
}

}