Problem
Given an array of integers, sort them by their frequencies. If two elements have the same frequencies, sort them by their indices.
Sample Input
1, 1, 2, 3, 3, 3
Sample Output
3, 3, 3, 1, 1, 2
Approach
We can make our custom comparator in this approach. The comparator should:
- first compare the frequency of the two elements, if the frequency is the same,
- compare it using indices.
C++ Programming
#include<bits/stdc++.h> using namespace std; // Comparator function bool comparator(tuple<int, int, int> const& x, tuple<int, int, int> const& y) { // If two elements have different frequencies, then // the one which has more frequency should come first if (get<1>(x) != get<1>(y)) { return get<1>(x) > get<1>(y); } // else element with lower index should be smaller one else { return get<2>(x) < get<2>(y); } } void solve(int arr[], int n) { if (n < 2) { return; } unordered_map<int, pair<int, int>> mp; // append frequency of each array element into the map // and index of its first occurrence in the array for (int i = 0; i < n; i++) { if (mp.find(arr[i]) != mp.end()) { mp[arr[i]].first++; } else { mp[arr[i]] = make_pair(1, i); } } // vector of tuple to store elements, frequency and first occurrence vector<tuple<int, int, int>> vp; for (auto it: mp) { pair<int, int> p = it.second; vp.push_back(make_tuple(it.first, p.first, p.second)); } // sort the elements using custom comparator sort(vp.begin(), vp.end(), comparator); int a, b, c, k = 0; for (auto element: vp) { tie(a, b, c) = element; for (int j = 0; j < b; j++) { arr[k++] = a; } } } int main() { int a[] = {1, 1, 2, 3, 3, 3}; int n = sizeof(a) / sizeof(a[0]); solve(a, n); for (int i = 0; i < n; i++) { cout << a[i] << " "; } return 0; }
Output
3 3 3 1 1 2
Python Programming
# Create class having three member variables class Node: def __init__(self, value, index, count=0): self.value = value self.index = index self.count = count # Function to sort elements by frequency and index def solve(arr): if arr is None or len(arr) < 2: return mp = {} for i in range(len(arr)): mp.setdefault(arr[i], Node(arr[i], i)).count += 1 values = [*mp.values()] # Sort by custom comparator values.sort(key=lambda x: (-x.count, x.index)) k = 0 for element in values: for j in range(element.count): arr[k] = element.value k += 1 arr = [1, 1, 2, 2, 3, 3, 3] solve(arr) print(arr)
Output
[3, 3, 3, 2, 2, 1]
Java Programming
import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class Node implements Comparable<Node> { int value, count, index; public Node(int value, int count, int index) { this.value = value; this.count = count; this.index = index; } public int compareTo(Node obj) { // If two elements have different frequencies if (this.count != obj.count) { return obj.count - this.count; } // If two elements have the same frequencies return this.index - obj.index; } } class Main { public static void solve(int[] arr) { if (arr.length < 2) { return; } // insert frequency and first index of element Map<Integer, Node> mp = new HashMap<>(); for (int i = 0; i < arr.length; i++) { mp.putIfAbsent(arr[i], new Node(arr[i], 0, i)); mp.get(arr[i]).count++; } // sort the values by custom comparator List<Node> values = mp.values().stream() .sorted() .collect(Collectors.toList()); int k = 0; for (Node data: values) { for (int j = 0; j < data.count; j++) { arr[k++] = data.value; } } } public static void main(String[] args) { int[] arr = { 1, 2, 2, 3, 3, 3 }; solve(arr); System.out.println(Arrays.toString(arr)); } }
Output
[3, 3, 3, 2, 2, 1]
People are also reading:
- Hybrid QuickSort Algorithm
- Quicksort using Dutch National Flag Algorithm
- Quicksort algorithm using Hoare’s partitioning scheme
- In-place vs out-of-place algorithms
- Minimum Edit Distance
- The Stock Span Problem
- Print Triangle Using * Character
- Subset Sum Problem
- Reverse a Linked List
- Maximum size square sub-matrices with all 1’s
Leave a Comment on this Post