Open In App

Sort Array according to modulus of their values with their frequencies

Last Updated : 28 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr containing N positive integers, sort them according to the increasing modulus of their values with their frequencies.

Example:

Input: arr[]={1, 1, 5, 3, 2, 3, 3, 3, 4, 5, 4, 5}
Output: 2 4 4 1 1 5 5 5 3 3 3 3 
Explanation:
The elements are sorted in the following order:
2 % frequency(2) = 2 % 1 = 0
4 % frequency(4) = 4 % 2 = 0
1 % frequency(1) = 1 % 2 = 1
5 % frequency(5) = 5 % 3 = 2
3 % frequency(4) = 3 % 4 = 3

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

Approach: To solve this question, store the frequencies of each number in a map and then create a custom comparator, which will do the sorting. That compare function will accept two integer values, say A and B as parameters and the condition in that comparator to sort the array is:

(A % frequency(A)) > (B % frequency(B))

Algorithm:

  1. Create an unordered map to store the frequencies of each number in the array.
  2. Sort the array using a custom comparator that compares the modulus of the values of two elements in the array with their respective frequencies.
  3. If the modulus is the same, compare the values of the elements and return true if the first element is smaller than the second element.
  4. If the modulus is not the same, compare the modulus of the two elements and return true if the modulus of the first element is smaller than the modulus of the second element.
  5. Print the sorted array.

Pseudocode:

function customSort(array):
    freq_map = empty unordered map
    for element in array:
        increment the frequency of element in freq_map
    sort array using a custom comparator:
        if modulus of A with freq[A] is equal to modulus of B with freq[B]:
            return A < B
        else:
            return modulus of A with freq[A] < modulus of B with freq[B]
    print the sorted array

Below is the implementation of the above approach.

C++




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to sort the numbers in an array
// according to the modulus of their values
// with their frequencies
void customSort(vector<int>& arr)
{
 
    // Map to store
    // the frequencies of each number
    unordered_map<int, int> freq;
    for (auto x : arr) {
        freq[x]++;
    }
 
    // Sorting them using
    // a custom comparator
    sort(arr.begin(), arr.end(),
         [&](int A, int B) {
             if (A % freq[A] == B % freq[B]) {
                 return A < B;
             }
             return A % freq[A] < B % freq[B];
         });
 
    // Printing the numbers
    for (auto x : arr) {
        cout << x << ' ';
    }
}
 
// Driver Code
int main()
{
    vector<int> arr = { 2, 9, 8, 2, 8,
                        9, 2, 8, 5 };
    customSort(arr);
}


Java




// Java code for the above approach
import java.util.*;
 
class GFG{
 
// Function to sort the numbers in an array
// according to the modulus of their values
// with their frequencies
static void customSort(Integer []arr)
{
 
    // Map to store
    // the frequencies of each number
    HashMap<Integer,Integer> freq = new HashMap<Integer,Integer>();
    for (int x : arr) {
        if(freq.containsKey(x)){
            freq.put(x, freq.get(x)+1);
        }
        else{
            freq.put(x, 1);
        }
    }
 
    // Sorting them using
    // a custom comparator
    Arrays.sort(arr, new Comparator<Integer>(){
  
        @Override
        public int compare(Integer a, Integer b)
        {
            // If both are odd or even
            // then sorting in increasing order
            if ((a % freq.get(a)) == (b % freq.get(b))) {
                return a < b?-1:1;
            }
  
            // Sorting on the basis of last bit if
            // if one is odd and the other one is even
            return ((a % freq.get(a)) < (b % freq.get(b)))?-1:1;
        }
          
    });
    // Printing the numbers
    for (int x : arr) {
        System.out.print(x +" ");
    }
}
 
// Driver Code
public static void main(String[] args)
{
    Integer []arr = { 2, 9, 8, 2, 8,
                        9, 2, 8, 5 };
    customSort(arr);
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python3 code for the above approach
 
# Function to sort the numbers in an array
# according to the modulus of their values
# with their frequencies
from collections import OrderedDict
from filecmp import cmp
from functools import cmp_to_key
 
freq = {}
 
def custom_sort(A, B):
     
    global freq
 
    if (A % freq[A] == B % freq[B]):
        return A - B
 
    return ((A % freq[A]) - (B % freq[B]))
 
def arr_sort(a,b):
    return a[0] - b[0]
 
def customSort(arr):
 
    global freq
     
    # Map to store
    # the frequencies of each number
    for x in arr :
        if x in freq:
            freq[x] = freq[x] + 1
        else:
            freq[x] = 1
 
    freq = OrderedDict(sorted(freq.items(),key = cmp_to_key(arr_sort)))
 
    # Sorting them using
    # a custom comparator
    arr.sort(key = cmp_to_key(custom_sort))
 
    # Printing the numbers
    for x in arr:
        print(x,end = ' ')
 
# Driver Code
arr = [2, 9, 8, 2, 8, 9, 2, 8, 5]
customSort(arr)
 
# This code is contributed by shinjanpatra


C#




// C# code for the above approach
 
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to sort the numbers in an array
    // according to the modulus of their values
    // with their frequencies
    static void customSort(int[] arr)
    {
 
        // Map to store
        // the frequencies of each number
        Dictionary<int, int> freq = new Dictionary<int, int>();
        foreach (int x in arr)
        {
            if (freq.ContainsKey(x))
            {
                freq[x] += 1;
            }
            else
            {
                freq[x] = 1;
            }
        }
 
        // Sorting them using
        // a custom comparator
        Array.Sort(arr, (a, b)
             =>
        {
            // If both are odd or even
            // then sorting in increasing order
            if ((a % freq[a]) == (b % freq[b]))
            {
                return a < b ? -1 : 1;
            }
 
            // Sorting on the basis of last bit if
            // if one is odd and the other one is even
            return ((a % freq[a]) < (b % freq[b])) ? -1 : 1;
        });
        // Printing the numbers
 
        foreach (int x in arr)
        {
            Console.Write(x + " ");
        }
    }
 
    // Driver Code
    public static void Main()
    {
        int[] arr = { 2, 9, 8, 2, 8,
                        9, 2, 8, 5 };
        customSort(arr);
    }
}
 
// This code is contributed by Saurabh Jaiswal


Javascript




<script>
// Javascript code for the above approach
 
// Function to sort the numbers in an array
// according to the modulus of their values
// with their frequencies
function customSort(arr) {
 
    // Map to store
    // the frequencies of each number
    let freq = new Map();
    for (x of arr) {
        if (freq.has(x)) {
            freq.set(x, freq.get(x) + 1)
        } else {
            freq.set(x, 1)
        }
    }
 
    freq = new Map([...freq].sort((a, b) => a[0] - b[0]));
 
 
    // Sorting them using
    // a custom comparator
    arr.sort((A, B) => {
        if (A % freq.get(A) == B % freq.get(B)) {
            return A - B;
        }
 
        return ((A % freq.get(A)) - (B % freq.get(B)));
    });
 
    // Printing the numbers
    for (x of arr) {
        document.write(x + ' ');
    }
}
 
// Driver Code
let arr = [2, 9, 8, 2, 8, 9, 2, 8, 5];
customSort(arr);
 
// This code is contributed by gfgking.
</script>


Output

5 9 9 2 2 2 8 8 8 

Time Complexity: O(N*log2N) as sorting takes N*log2N time.
Auxiliary Space: O(N)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads