Given an array of integers, sort the array (in descending order) according to count of set bits in binary representation of array elements.
Note: For integers having same number of set bits in their binary representation, sort according to their position in the original array i.e., a stable sort.
Examples:
Input: arr[] = [5, 2, 3, 9, 4, 6, 7, 15, 32]
Output: 15 7 5 3 9 6 2 4 32
Explanation: The integers in their binary representation are:
15 - 1111
7 - 0111
5 - 0101
3 - 0011
9 - 1001
6 - 0110
2 - 0010
4 - 0100
32 - 100000
Hence the non-increasing sorted order is: {15}, {7}, {5, 3, 9, 6}, {2, 4, 32}.Input: arr[] = [1, 2, 3, 4, 5, 6]
Output: 3 5 6 1 2 4
Explanation: The integers in their binary representation are:
3 - 0011
5 - 0101
6 - 0110
1 - 0001
2 - 0010
4 - 0100
hence the non-increasing sorted order is {3, 5, 6}, {1, 2, 4}.
Table of Content
[Naive Approach] - Using Inbuilt Sort Function - O(n * log n) Time and O(1) Space
The idea is to use the inbuilt sort function and custom comparator to sort the array according to set-bit count.
Dry run for arr[] = [5, 4, 7, 15] :
- Compute set bits for each element.
5 (binary : 101) = 2 bits, 4 (binary : 100) = 1 bit, 7 (binary : 111) = 3 bits and 15 (binary : 1111) = 4 bits - Group elements based on set bits (preserving original order).
4 bits = [15], 3 bits = [7], 2 bits = [5], 1 bit = [4] - Arrange groups in descending order of set bits.
[15] + [7] + [5] + [4]
Final output: 15 7 5 4
#include <bits/stdc++.h>
using namespace std;
// Function to count set bits in an integer
// Since, we are dealing with intergers only
// so maximum bits in int can be 32
// therefore time complexity of this function is O(1) i.e. constant.
int countBits(int n)
{
int cnt = 0;
while (n > 0)
{
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
vector<int> sortBySetBitCount(vector<int> &arr)
{
// custom comparator of sort
auto comp = [&](int a, int b) {
int cnt1 = countBits(a);
int cnt2 = countBits(b);
return cnt1 > cnt2;
};
// stable sort preserves order for equal bit counts
stable_sort(arr.begin(), arr.end(), comp);
return arr;
}
// Main function
int main()
{
vector<int> arr = {5, 2, 3, 9, 4, 6, 7, 15, 32};
vector<int> res = sortBySetBitCount(arr);
// Print result
for (int i = 0; i < arr.size(); i++)
cout << res[i] << " ";
return 0;
}
import java.util.*;
class GFG {
// Function to count set bits in an integer
// Since, we are dealing with integers only
// so maximum bits in int can be 32
// therefore time complexity of this function is O(1)
// i.e. constant.
static int countBits(int n)
{
int cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort array based on set bit count
static ArrayList<Integer> sortBySetBitCount(int[] arr)
{
// Convert int[] to Integer[] for custom comparator
Integer[] arrInteger = new Integer[arr.length];
for (int i = 0; i < arr.length; i++) {
arrInteger[i] = arr[i];
}
// custom comparator
Arrays.sort(arrInteger, (a, b) -> {
int count1 = countBits(a);
int count2 = countBits(b);
// descending order of set bits
if (count1 != count2) {
return count2 - count1;
}
// maintain original order (stable behavior)
return 0;
});
// Convert array to ArrayList and return
return new ArrayList<>(Arrays.asList(arrInteger));
}
// Main function
public static void main(String[] args)
{
int[] arr = { 5, 2, 3, 9, 4, 6, 7, 15, 32 };
ArrayList<Integer> result = sortBySetBitCount(arr);
// Print result
for (int x : result) {
System.out.print(x + " ");
}
}
}
# Function to count set bits in an integer
# Since, we are dealing with integers only
# so maximum bits in int can be 32
# therefore time complexity of this function is O(1) i.e. constant.
def countBits(n):
cnt = 0
while n > 0:
cnt += (n & 1)
n = n >> 1
return cnt
# Function to sort an array according to bit count
def sortBySetBitCount(arr):
# custom comparator of sort
# Python uses key instead of comparator
arr.sort(key=lambda x: countBits(x), reverse=True)
return arr
# Driver code
arr = [5, 2, 3, 9, 4, 6, 7, 15, 32]
res = sortBySetBitCount(arr)
# Print result
for x in res:
print(x, end=" ")
using System;
using System.Collections.Generic;
class GFG {
// Function to count set bits in an integer
// Since, we are dealing with integers only
// so maximum bits in int can be 32
// therefore time complexity of this function is O(1)
// i.e. constant.
static int countBits(int n)
{
int cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
static List<int> sortBySetBitCount(int[] arr)
{
// store value and original index
var list = new List<(int val, int idx)>();
for (int i = 0; i < arr.Length; i++) {
list.Add((arr[i], i));
}
list.Sort((a, b) = > {
int count1 = countBits(a.val);
int count2 = countBits(b.val);
// descending order of set bits
if (count1 != count2)
return count2 - count1;
// preserve original order (stability) if count
// of bits are same
return a.idx - b.idx;
});
// extract result
List<int> res = new List<int>();
foreach(var item in list) res.Add(item.val);
return res;
}
// Main function
static void Main()
{
int[] arr = { 5, 2, 3, 9, 4, 6, 7, 15, 32 };
List<int> res = sortBySetBitCount(arr);
// Print result
foreach(int x in res) Console.Write(x + " ");
}
}
// Function to count set bits in an integer
// Since, we are dealing with integers only
// so maximum bits in int can be 32
// therefore time complexity of this function is O(1) i.e. constant.
function countBits(n) {
let cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
function sortBySetBitCount(arr) {
// custom comparator of sort
arr.sort((a, b) => {
let cnt1 = countBits(a);
let cnt2 = countBits(b);
// descending order of set bits
return cnt2 - cnt1;
});
return arr;
}
// Driver code
let arr = [5, 2, 3, 9, 4, 6, 7, 15, 32];
let res = sortBySetBitCount(arr);
// Print result
console.log(res.join(" "));
Output
15 7 5 3 9 6 2 4 32
[Expected Approach] - Using Counting Sort - O(n) Time and O(n) Space
The idea is to use counting sort to arrange the elements in descending order of count of set-bits. For any integer, assuming the minimum and maximum set-bits can be 1 and 31 respectively, create an array count[][] of size 32, where each element count[i] stores the elements of given array with count of their set bits equal to i. After inserting all the elements, traverse count[][] in reverse order, and store the elements at each index in the given array.
Dry run for arr[] = [5, 4, 7, 15] :
- Compute set bits and place into buckets:
5 (binary : 101) = 2 bits, count[2] = [5]
4 (binary : 100) = 1 bit, count[1] = [4]
7 (binary : 111) = 3 bits, count[3] = [7]
15 (binary : 1111) = 4 bits, count[4] = [15] - Buckets after filling:
count[4] = [15], count[3] = [7], count[2] = [5], count[1] = [4], others = [] - Build result (from highest bit count to lowest):
For i=31 = []
For i=30 = []
...
For i=4 = [15]
For i=3 = [15, 7]
For i=2 = [15, 7, 5]
For i=1 = [15, 7, 5, 4]
For i=0 = no change
Final output is : 15 7 5 4
#include <bits/stdc++.h>
using namespace std;
// Function to count set bits in an integer
int countBits(int n)
{
int cnt = 0;
while (n > 0)
{
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
vector<int> sortBySetBitCount(vector<int> &arr)
{
int n = arr.size();
// Create a 2d array to map array elements
// to their corresponding set bit count
vector<vector<int>> count(32);
// insert elements in the 2d array
for (int i = 0; i < n; i++)
{
int setBit = countBits(arr[i]);
count[setBit].push_back(arr[i]);
}
// vector to store ans
vector<int> res;
// Traverse through all bit counts
for (int i = 31; i >= 0; i--)
{
// Traverse through all elements
// of current bit count
for (int k = 0; k < count[i].size(); k++)
{
res.push_back(count[i][k]);
}
}
return res;
}
// Main function
int main()
{
vector<int> arr = {5, 2, 3, 9, 4, 6, 7, 15, 32};
vector<int> res = sortBySetBitCount(arr);
// Print result
for (int i = 0; i < arr.size(); i++)
cout << res[i] << " ";
return 0;
}
import java.util.*;
class GfG {
// Function to count set bits in an integer
static int countBits(int n)
{
int cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
static ArrayList<Integer> sortBySetBitCount(int[] arr)
{
int n = arr.length;
// Create a 2d array to map array elements
// to their corresponding set bit count
ArrayList<ArrayList<Integer> > count = new ArrayList<>();
for (int i = 0; i < 32; i++) {
count.add(new ArrayList<>());
}
// insert elements in the 2d array
for (int i = 0; i < n; i++) {
int setBit = countBits(arr[i]);
count.get(setBit).add(arr[i]);
}
// array to store ans
ArrayList<Integer> res = new ArrayList<Integer>();
// Traverse through all bit counts
for (int i = 31; i >= 0; i--) {
// Traverse through all elements
// of current bit count
ArrayList<Integer> curr = count.get(i);
for (int k = 0; k < curr.size(); k++) {
res.add(curr.get(k));
}
}
return res;
}
// Main function
public static void main(String[] args)
{
int[] arr = { 5, 2, 3, 9, 4, 6, 7, 15, 32 };
ArrayList<Integer> res = sortBySetBitCount(arr);
// Print result
for (int i = 0; i < arr.length; i++)
System.out.print(res.get(i) + " ");
}
}
# Function to count set bits in an integer
def countBits(n):
cnt = 0
while n > 0:
cnt += (n & 1)
n = n >> 1
return cnt
# Function to sort an array according to bit count
def sortBySetBitCount(arr):
n = len(arr)
# Create a 2d array to map array elements
# to their corresponding set bit count
count = [[] for _ in range(32)]
# insert elements in the 2d array
for i in range(n):
setBit = countBits(arr[i])
count[setBit].append(arr[i])
# list to store ans
res = []
# Traverse through all bit counts
for i in range(31, -1, -1):
# Traverse through all elements
# of current bit count
for k in range(len(count[i])):
res.append(count[i][k])
return res
# Driver Code
if __name__ == "__main__":
arr = [5, 2, 3, 9, 4, 6, 7, 15, 32]
res = sortBySetBitCount(arr)
# Print result
for i in range(len(arr)):
print(res[i], end=" ")
using System;
using System.Collections.Generic;
class GfG {
// Function to count set bits in an integer
static int countBits(int n) {
int cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
static List<int> sortBySetBitCount(int[] arr) {
int n = arr.Length;
// Create a 2d array to map array elements
// to their corresponding set bit count
List<List<int>> count = new List<List<int>>();
for (int i = 0; i < 32; i++) {
count.Add(new List<int>());
}
// insert elements in the 2d array
for (int i = 0; i < n; i++) {
int setBit = countBits(arr[i]);
count[setBit].Add(arr[i]);
}
// list to store ans
List<int> res = new List<int>();
// Traverse through all bit counts
for (int i = 31; i >= 0; i--) {
// Traverse through all elements
// of current bit count
for (int k = 0; k < count[i].Count; k++) {
res.Add(count[i][k]);
}
}
return res;
}
// Main function
static void Main() {
int[] arr = {5, 2, 3, 9, 4, 6, 7, 15, 32};
List<int> res = sortBySetBitCount(arr);
// Print result
for (int i = 0; i < arr.Length; i++)
Console.Write(res[i] + " ");
}
}
// Function to count set bits in an integer
function countBits(n)
{
let cnt = 0;
while (n > 0) {
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
// Function to sort an array according to bit count
function sortBySetBitCount(arr)
{
let n = arr.length;
// Create a 2d array to map array elements
// to their corresponding set bit count
let count = [];
for (let i = 0; i < 32; i++) {
count.push([]);
}
// insert elements in the 2d array
for (let i = 0; i < n; i++) {
let setBit = countBits(arr[i]);
count[setBit].push(arr[i]);
}
// array to store ans
let res = [];
// Traverse through all bit counts
for (let i = 31; i >= 0; i--) {
// Traverse through all elements
// of current bit count
for (let k = 0; k < count[i].length; k++) {
res.push(count[i][k]);
}
}
return res;
}
// Driver code
let arr = [ 5, 2, 3, 9, 4, 6, 7, 15, 32 ];
let res = sortBySetBitCount(arr);
// Print result
let ans = "";
for (let i = 0; i < arr.length; i++)
ans += res[i] + " ";
console.log(ans.trim());
Output
15 7 5 3 9 6 2 4 32