Sort an array according to count of set bits
Last Updated :
05 Apr, 2023
Given an array of positive integers, sort the array in decreasing order of count of set bits in binary representations of array elements. For integers having the same number of set bits in their binary representation, sort according to their position in the original array i.e., a stable sort. For example, if the input array is {3, 5}, then the output array should also be {3, 5}. Note that both 3 and 5 have the same number set bits.
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 -10000
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:
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}
Method 1: Simple
- Create an auxiliary array and store the set-bit counts of all integers in the aux array
- Simultaneously sort both arrays according to the non-increasing order of auxiliary array. (Note that we need to use a stable sort algorithm)
Before sort:
int arr[] = {1, 2, 3, 4, 5, 6};
int aux[] = {1, 1, 2, 1, 2, 2}
After sort:
arr = {3, 5, 6, 1, 2, 4}
aux = {2, 2, 2, 1, 1, 1}
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int countBits( int a)
{
int count = 0;
while (a) {
if (a & 1)
count += 1;
a = a >> 1;
}
return count;
}
void insertionSort( int arr[], int aux[], int n)
{
for ( int i = 1; i < n; i++) {
int key1 = aux[i];
int key2 = arr[i];
int j = i - 1;
while (j >= 0 && aux[j] < key1) {
aux[j + 1] = aux[j];
arr[j + 1] = arr[j];
j = j - 1;
}
aux[j + 1] = key1;
arr[j + 1] = key2;
}
}
void sortBySetBitCount( int arr[], int n)
{
int aux[n];
for ( int i = 0; i < n; i++)
aux[i] = countBits(arr[i]);
insertionSort(arr, aux, n);
}
void printArr( int arr[], int n)
{
for ( int i = 0; i < n; i++)
cout << arr[i] << " " ;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
sortBySetBitCount(arr, n);
printArr(arr, n);
return 0;
}
|
C
#include <stdio.h>
int countBits( int a)
{
int count = 0;
while (a) {
if (a & 1)
count += 1;
a = a >> 1;
}
return count;
}
void insertionSort( int arr[], int aux[], int n)
{
for ( int i = 1; i < n; i++) {
int key1 = aux[i];
int key2 = arr[i];
int j = i - 1;
while (j >= 0 && aux[j] < key1) {
aux[j + 1] = aux[j];
arr[j + 1] = arr[j];
j = j - 1;
}
aux[j + 1] = key1;
arr[j + 1] = key2;
}
}
void sortBySetBitCount( int arr[], int n)
{
int aux[n];
for ( int i = 0; i < n; i++)
aux[i] = countBits(arr[i]);
insertionSort(arr, aux, n);
}
void printArr( int arr[], int n)
{
for ( int i = 0; i < n; i++)
printf ( "%d " , arr[i]);
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
sortBySetBitCount(arr, n);
printArr(arr, n);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int countBits( int a)
{
int count = 0 ;
while (a > 0 ) {
if ((a & 1 ) > 0 )
count += 1 ;
a = a >> 1 ;
}
return count;
}
static void insertionSort( int arr[], int aux[], int n)
{
for ( int i = 1 ; i < n; i++) {
int key1 = aux[i];
int key2 = arr[i];
int j = i - 1 ;
while (j >= 0 && aux[j] < key1) {
aux[j + 1 ] = aux[j];
arr[j + 1 ] = arr[j];
j = j - 1 ;
}
aux[j + 1 ] = key1;
arr[j + 1 ] = key2;
}
}
static void sortBySetBitCount( int arr[], int n)
{
int aux[] = new int [n];
for ( int i = 0 ; i < n; i++)
aux[i] = countBits(arr[i]);
insertionSort(arr, aux, n);
}
static void printArr( int arr[], int n)
{
for ( int i = 0 ; i < n; i++)
System.out.print(arr[i] + " " );
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int n = arr.length;
sortBySetBitCount(arr, n);
printArr(arr, n);
}
}
|
Python3
def countBits(a):
count = 0
while (a):
if (a & 1 ):
count + = 1
a = a>> 1
return count
def insertionSort(arr,aux, n):
for i in range ( 1 ,n, 1 ):
key1 = aux[i]
key2 = arr[i]
j = i - 1
while (j > = 0 and aux[j] < key1):
aux[j + 1 ] = aux[j]
arr[j + 1 ] = arr[j]
j = j - 1
aux[j + 1 ] = key1
arr[j + 1 ] = key2
def sortBySetBitCount(arr, n):
aux = [ 0 for i in range (n)]
for i in range ( 0 ,n, 1 ):
aux[i] = countBits(arr[i])
insertionSort(arr, aux, n)
def printArr(arr, n):
for i in range ( 0 ,n, 1 ):
print (arr[i],end = " " )
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
n = len (arr)
sortBySetBitCount(arr, n)
printArr(arr, n)
|
C#
using System;
public class GFG
{
static int countBits( int a)
{
int count = 0;
while (a > 0)
{
if ((a & 1) > 0)
count += 1;
a = a >> 1;
}
return count;
}
static void insertionSort( int []arr,
int []aux, int n)
{
for ( int i = 1; i < n; i++)
{
int key1 = aux[i];
int key2 = arr[i];
int j = i - 1;
while (j >= 0 && aux[j] < key1)
{
aux[j + 1] = aux[j];
arr[j + 1] = arr[j];
j = j - 1;
}
aux[j + 1] = key1;
arr[j + 1] = key2;
}
}
static void sortBySetBitCount( int []arr,
int n)
{
int []aux = new int [n];
for ( int i = 0; i < n; i++)
aux[i] = countBits(arr[i]);
insertionSort(arr, aux, n);
}
static void printArr( int []arr, int n)
{
for ( int i = 0; i < n; i++)
Console.Write(arr[i] + " " );
}
static public void Main ()
{
int []arr = {1, 2, 3, 4, 5, 6};
int n = arr.Length;
sortBySetBitCount(arr, n);
printArr(arr, n);
}
}
|
Javascript
<script>
function countBits(a)
{
let count = 0;
while (a > 0)
{
if ((a & 1) > 0)
count+= 1;
a = a >> 1;
}
return count;
}
function insertionSort(arr,aux,n)
{
for (let i = 1; i < n; i++)
{
let key1 = aux[i];
let key2 = arr[i];
let j = i - 1;
while (j >= 0 && aux[j] < key1)
{
aux[j + 1] = aux[j];
arr[j + 1] = arr[j];
j = j - 1;
}
aux[j + 1] = key1;
arr[j + 1] = key2;
}
}
function sortBySetBitCount(arr,n)
{
let aux = new Array(n);
for (let i = 0; i < n; i++)
aux[i] = countBits(arr[i]);
insertionSort(arr, aux, n);
}
function printArr(arr,n)
{
for (let i = 0; i < n; i++)
document.write(arr[i] + " " );
}
let arr=[1, 2, 3, 4, 5, 6];
let n = arr.length;
sortBySetBitCount(arr, n);
printArr(arr, n);
</script>
|
Auxiliary Space: O(n)
Time complexity: O(n2)
Note: Time complexity can be improved to O(nLogn) by using a stable O(nlogn) sorting algorithm.
Method 2: Using std::sort()
Using custom comparator of std::sort to sort the array according to set-bit count
C++
#include <bits/stdc++.h>
using namespace std;
int countBits( int a)
{
int count = 0;
while (a) {
if (a & 1)
count += 1;
a = a >> 1;
}
return count;
}
int cmp( int a, int b)
{
int count1 = countBits(a);
int count2 = countBits(b);
if (count1 <= count2)
return false ;
return true ;
}
void sortBySetBitCount( int arr[], int n)
{
stable_sort(arr, arr + n, cmp);
}
void printArr( int arr[], int n)
{
for ( int i = 0; i < n; i++)
cout << arr[i] << " " ;
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
sortBySetBitCount(arr, n);
printArr(arr, n);
return 0;
}
|
C
#include <stdio.h>
int countBits( int a)
{
int count = 0;
while (a) {
if (a & 1)
count += 1;
a = a >> 1;
}
return count;
}
int cmp( int a, int b)
{
int count1 = countBits(a);
int count2 = countBits(b);
if (count1 <= count2)
return false ;
return true ;
}
void sortBySetBitCount( int arr[], int n)
{
stable_sort(arr, arr + n, cmp);
}
void printArr( int arr[], int n)
{
for ( int i = 0; i < n; i++)
printf ( "%d " , arr[i]);
}
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
sortBySetBitCount(arr, n);
printArr(arr, n);
return 0;
}
|
Java
import java.util.Arrays;
import java.util.Comparator;
public class Test {
public static void main(String[] args)
{
Integer arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int n = 6 ;
sortBySetBitCount(arr, n);
printArr(arr, n);
System.out.println();
}
private static void printArr(Integer[] arr, int n)
{
for ( int i = 0 ; i < n; i++)
System.out.print(arr[i] + " " );
}
private static Integer[] sortBySetBitCount(
Integer[] arr, int n)
{
Arrays.sort(arr, new Comparator<Integer>() {
@Override
public int compare(Integer arg0, Integer arg1)
{
int c1 = Integer.bitCount(arg0);
int c2 = Integer.bitCount(arg1);
if (c1 <= c2)
return 1 ;
else
return - 1 ;
}
});
return arr;
}
}
|
Python3
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
n = len (arr)
arr = [(arr[i], i) for i in range (n)]
def countSetBits(val):
cnt = 0
while val:
cnt + = val % 2
val = val / / 2
return cnt
sorted_arr = sorted (arr, key = lambda val: (
countSetBits(val[ 0 ]), n - val[ 1 ]), reverse = True )
sorted_arr = [val[ 0 ] for val in sorted_arr]
print (sorted_arr)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class Program {
static void Main( string [] args) {
int [] arr = {
1,
2,
3,
4,
5,
6
};
int n = 6;
SortBySetBitCount(arr, n);
PrintArr(arr, n);
Console.WriteLine();
}
private static void PrintArr( int [] arr, int n) {
for ( int i = 0; i < n; i++)
Console.Write(arr[i] + " " );
}
private static void SortBySetBitCount( int [] arr, int n) {
Array.Sort(arr, new CountComparer());
}
private class CountComparer: IComparer < int > {
public int Compare( int x, int y) {
int c1 = CountBits(x);
int c2 = CountBits(y);
if (c1 <= c2)
return 1;
else
return -1;
}
private int CountBits( int a) {
int count = 0;
while (a != 0) {
if ((a & 1) == 1)
count += 1;
a = a >> 1;
}
return count;
}
}
}
|
Javascript
<script>
function printArr(arr,n)
{
for (let i = 0; i < n; i++)
document.write(arr[i] + " " );
}
function sortBySetBitCount(arr,n)
{
arr.sort( function (a,b){
c1 = Number(a.toString(2).split( "" ).sort().join( "" )).toString().length;
c2 = Number(b.toString(2).split( "" ).sort().join( "" )).toString().length;
return c2-c1;
})
}
let arr = [1, 2, 3, 4, 5, 6 ];
let n = 6;
sortBySetBitCount(arr, n);
printArr(arr, n);
document.write();
</script>
|
Auxiliary Space: O(1)
Time complexity: O(n log n)
Method 3: Counting Sort based
This problem can be solved in O(n) time. The idea is similar to counting sort.
Note: There can be a minimum 1 set-bit and only a maximum of 31set-bits in an integer.
Steps (assuming that an integer takes 32 bits):
- Create a vector “count” of size 32. Each cell of count i.e., count[i] is another vector that stores all the elements whose set-bit-count is i
- Traverse the array and do the following for each element:
- Count the number set-bits of this element. Let it be ‘setbitcount’
- count[setbitcount].push_back(element)
- Traverse ‘count’ in reverse fashion(as we need to sort in non-increasing order) and modify the array.
C++
#include <bits/stdc++.h>
using namespace std;
int countBits( int a)
{
int count = 0;
while (a)
{
if (a & 1 )
count+= 1;
a = a>>1;
}
return count;
}
void sortBySetBitCount( int arr[], int n)
{
vector<vector< int > > count(32);
int setbitcount = 0;
for ( int i=0; i<n; i++)
{
setbitcount = countBits(arr[i]);
count[setbitcount].push_back(arr[i]);
}
int j = 0;
for ( int i=31; i>=0; i--)
{
vector< int > v1 = count[i];
for ( int i=0; i<v1.size(); i++)
arr[j++] = v1[i];
}
}
void printArr( int arr[], int n)
{
for ( int i=0; i<n; i++)
cout << arr[i] << " " ;
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6};
int n = sizeof (arr)/ sizeof (arr[0]);
sortBySetBitCount(arr, n);
printArr(arr, n);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int countBits( int a)
{
int count = 0 ;
while (a > 0 )
{
if ((a & 1 ) > 0 )
count += 1 ;
a = a >> 1 ;
}
return count;
}
static void sortBySetBitCount( int arr[],
int n)
{
Vector<Integer> []count =
new Vector[ 32 ];
for ( int i = 0 ;
i < count.length; i++)
count[i] = new Vector<Integer>();
int setbitcount = 0 ;
for ( int i = 0 ; i < n; i++)
{
setbitcount = countBits(arr[i]);
count[setbitcount].add(arr[i]);
}
int j = 0 ;
for ( int i = 31 ; i >= 0 ; i--)
{
Vector<Integer> v1 = count[i];
for ( int p = 0 ; p < v1.size(); p++)
arr[j++] = v1.get(p);
}
}
static void printArr( int arr[],
int n)
{
for ( int i = 0 ; i < n; i++)
System.out.print(arr[i] + " " );
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int n = arr.length;
sortBySetBitCount(arr, n);
printArr(arr, n);
}
}
|
Python3
def countBits(a):
count = 0
while (a):
if (a & 1 ):
count + = 1
a = a>> 1
return count
def sortBySetBitCount(arr,n):
count = [[] for i in range ( 32 )]
setbitcount = 0
for i in range (n):
setbitcount = countBits(arr[i])
count[setbitcount].append(arr[i])
j = 0
for i in range ( 31 , - 1 , - 1 ):
v1 = count[i]
for i in range ( len (v1)):
arr[j] = v1[i]
j + = 1
def printArr(arr, n):
print ( * arr)
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
n = len (arr)
sortBySetBitCount(arr, n)
printArr(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int countBits( int a)
{
int count = 0;
while (a > 0)
{
if ((a & 1) > 0 )
count += 1;
a = a >> 1;
}
return count;
}
static void sortBySetBitCount( int []arr,
int n)
{
List< int > []count =
new List< int >[32];
for ( int i = 0;
i < count.Length; i++)
count[i] = new List< int >();
int setbitcount = 0;
for ( int i = 0; i < n; i++)
{
setbitcount = countBits(arr[i]);
count[setbitcount].Add(arr[i]);
}
int j = 0;
for ( int i = 31; i >= 0; i--)
{
List< int > v1 = count[i];
for ( int p = 0; p < v1.Count; p++)
arr[j++] = v1[p];
}
}
static void printArr( int []arr,
int n)
{
for ( int i = 0; i < n; i++)
Console.Write(arr[i] + " " );
}
public static void Main(String[] args)
{
int []arr = {1, 2, 3, 4, 5, 6};
int n = arr.Length;
sortBySetBitCount(arr, n);
printArr(arr, n);
}
}
|
Javascript
<script>
function countBits(a)
{
let count = 0;
while (a > 0)
{
if ((a & 1) > 0 )
count += 1;
a = a >> 1;
}
return count;
}
function sortBySetBitCount(arr,n)
{
let count = new Array(32);
for (let i = 0;
i < count.length; i++)
count[i] = [];
let setbitcount = 0;
for (let i = 0; i < n; i++)
{
setbitcount = countBits(arr[i]);
count[setbitcount].push(arr[i]);
}
let j = 0;
for (let i = 31; i >= 0; i--)
{
let v1 = count[i];
for (let p = 0; p < v1.length; p++)
arr[j++] = v1[p];
}
}
function printArr(arr,n)
{
for (let i = 0; i < n; i++)
document.write(arr[i] + " " );
}
let arr = [1, 2, 3, 4, 5, 6];
let n = arr.length;
sortBySetBitCount(arr, n);
printArr(arr, n);
</script>
|
Time complexity: O(n)
Auxiliary Space: O(n)
Method 4: Using MultiMap
Steps:
- Create a MultiMap whose key values will be the negative of the number of set-bits of the element.
- Traverse the array and do following for each element:
- Count the number set-bits of this element. Let it be ‘setBitCount’
- count.insert({(-1) * setBitCount, element})
- Traverse ‘count’ and print the second elements.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int setBitCount( int num){
int count = 0;
while ( num )
{
if ( num & 1)
count++;
num >>= 1;
}
return count;
}
void sortBySetBitCount( int arr[], int n)
{
multimap< int , int > count;
for ( int i = 0 ; i < n ; ++i )
{
count.insert({(-1) *
setBitCount(arr[i]), arr[i]});
}
for ( auto i : count)
cout << i.second << " " ;
cout << "\n" ;
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6};
int n = sizeof (arr)/ sizeof (arr[0]);
sortBySetBitCount(arr, n);
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static int setBitCount( int num)
{
int count = 0 ;
while ( num != 0 )
{
if ( (num & 1 ) != 0 )
count++;
num >>= 1 ;
}
return count;
}
static void sortBySetBitCount( int [] arr, int n)
{
ArrayList<ArrayList<Integer>> count = new ArrayList<ArrayList<Integer>>();
for ( int i = 0 ; i < n ; ++i )
{
count.add( new ArrayList<Integer>(Arrays.asList((- 1 ) * setBitCount(arr[i]), arr[i])));
}
Collections.sort(count, new Comparator<ArrayList<Integer>>() {
@Override
public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
return o1.get( 0 ).compareTo(o2.get( 0 ));
}
});
for ( int i = 0 ; i < count.size(); i++)
{
System.out.print(count.get(i).get( 1 ) + " " );
}
}
public static void main (String[] args)
{
int arr[] = { 1 , 2 , 3 , 4 , 5 , 6 };
int n = arr.length;
sortBySetBitCount(arr, n);
}
}
|
Python3
def setBitCount(num):
count = 0
while (num):
if (num & 1 ):
count + = 1
num = num >> 1
return count
def sortBySetBitCount(arr, n):
count = []
for i in range (n):
count.append([( - 1 ) *
setBitCount(arr[i]), arr[i]])
count.sort(key = lambda x:x[ 0 ])
for i in range ( len (count)):
print (count[i][ 1 ], end = " " )
arr = [ 1 , 2 , 3 , 4 , 5 , 6 ]
n = len (arr)
sortBySetBitCount(arr, n)
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int setBitCount( int num){
int count = 0;
while ( num != 0)
{
if ( (num & 1) != 0)
count++;
num >>= 1;
}
return count;
}
static void sortBySetBitCount( int [] arr, int n)
{
List<Tuple< int , int >> count = new List<Tuple< int , int >>();
for ( int i = 0 ; i < n ; ++i )
{
count.Add( new Tuple< int , int >((-1) * setBitCount(arr[i]), arr[i]));
}
count.Sort();
foreach (Tuple< int , int > i in count)
{
Console.Write(i.Item2 + " " );
}
Console.WriteLine();
}
static void Main() {
int [] arr = {1, 2, 3, 4, 5, 6};
int n = arr.Length;
sortBySetBitCount(arr, n);
}
}
|
Javascript
<script>
function setBitCount(num) {
count = 0
while (num) {
if (num & 1) {
count += 1
}
num = num >> 1
}
return count
}
function sortBySetBitCount(arr, n) {
let count = []
for (let i = 0; i < n; i++) {
count.push([(-1) * setBitCount(arr[i]), arr[i]])
}
count.sort((a, b) => a[0] - b[0])
for (let i = 0; i < count.length; i++)
document.write(count[i][1] + " " )
}
let arr = [1, 2, 3, 4, 5, 6]
let n = arr.length
sortBySetBitCount(arr, n)
</script>
|
Time complexity: O(n log n)
Auxiliary Space: O(n)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...