# Sort An Array According To The Set Bits Count in Java

An array containing natural numbers is given to us. Our task is to sort the input array as per the number of set bits in the binary representation of the elements present in the input array. That is, a number that has a greater number of set bits should come after the number that has a smaller number of set bits. If any two number has the same number of set bits, then show them in the same order in which they are shown in the input array. Assume that any of the numbers in the input array is able to fit in a 32-bit integer.

Example 1:

Input

int arr[] = {1, 4, 2, 8, 16, 64, 32, 128}

Output: {1, 4, 2, 8, 16, 64, 32, 128}

Explanation: First of all, let's see the binary representation of each of the numbers present in the input array.

1 -> 1, 4 -> 100, 2 -> 10, 8 -> 1000, 16 -> 10000, 64 -> 1000000, 32 -> 100000

128 -> 10000000

We see that every number in its binary representation contains only one set bit. Hence, the output contains the elements in the same order as they appear in the input array.

Example 2:

Input

int arr[] = {11, 24, 7, 28, 128, 60, 132, 16, 5}

Output: {128, 16, 24, 132, 5, 11, 7, 28, 60}

Explanation: First of all, let's see the binary representation of each of the numbers present in the input array.

11 -> 1011, 24 -> 11000, 7 -> 111, 28 -> 11100, 128 -> 10000000, 60 -> 111100, 132 -> 10000100, 16 -> 10000, 5 -> 1001

11 has 3 set bits. 24 has 2 set bits. 7 has 3 set bits. Similarly, we can compute the number of set bits for other numbers too. We see that numbers 16 and 128 have only one set bit, and 128 is coming before 16. Hence, the first two elements in the output are 128 and 16. 24, 132 and 5 have 2 set bits. Therefore, they are the next elements in the output. After that comes the turns of 11, 7, and 28, as they have 3 set bits. At last, comes the number 60.

We see that every number in its binary representation contains only one set bit. Hence, the output contains the elements in the same order as they appear in the input array.

## Approach: Using Map

Using a map, we can achieve the desired result. We will have to store make a hash map whose key is the number of set bits present in the number, and the value is a vector or array list that stores the number. Thus, for the input array {1, 2, 3, 4, 5}, the hash map will look like the following.

[1] -> {1, 2, 4} and [2] -> {3, 5}, where the value in the square brackets is key, and its corresponding list is the value. After that, we can use a loop (from 0 to 32), so we can easily display the output. Observe the following program for a better understanding.

FileName: SetBitCntSort.java

Output:

```For the input array:
1 4 2 8 16 64 32 128
The sorted arrange as per the set bits are:
1 4 2 8 16 64 32 128

For the input array:
11 24 7 28 128 60 132 16 5
The sorted arrange as per the set bits are:
128 16 24 132 5 11 7 28 60
```

Complexity Analysis: The addAll() method takes O(n) time, and the method is getting invoked n times. Thus, the total time complexity of the program is O(n2). The program is also using an auxiliary space, making the space complexity of the program O(n), where n is the total number of elements present in the input array.

We can be a bit miser in terms of time as well as space complexity. The illustration of the same is mentioned in the following approach.

## Approach: Using Customized Comparator

By making use of the customized comparator while invoking the inbuilt sort method (Comparator methods are the methods that are responsible for making a based on the sorting approach), we will be able to reduce the space complexity of the program. Following is the pseudo code of the comparator method:

Comparator(int n1, int n2):

If (cntSetBits(n1) > cntSetBits(n2))

return false;

else

return true;

The method makes the comparison of the set bits count in the numbers and it returns false if the set bits count is lesser in the second number; otherwise, it returns true because the sorting order is ascending. See the following program.

FileName: SetBitCntSort1.java

Output:

```For the input array:
1 4 2 8 16 64 32 128
The sorted arrange as per the set bits are:
1 4 2 8 16 64 32 128

For the input array:
11 24 7 28 128 60 132 16 5
The sorted arrange as per the set bits are:
128 16 24 132 5 11 7 28 60
```

Complexity Analysis: The time complexity of the program is O(n x log(n)), as the program is using the sorting technique. The space complexity of the program is the O(1), as the program is not using any data structure for storing any values.

Let's do some more optimization to reduce the time complexity.

## Approach: Counting Sort

Using counting sort also, one can sort the elements on the basis of set bits count.

Algorithm:

Step 1: Create a 2-D array list whose size will be 33. We are taking size 33 because every integer will fit in the 32-bit integer. The list at the zeroth index shows the element that has the zero set bit. The list at the 1st index shows the element that has a total of only one set bit, and so on.

Step 2: Now, start traversing all of the elements of the array and compute the set bits number for every element. Let the set bits count is 'cnt', and then the element should be pushed in the list at the index 'cnt' of the array.

Step 3: Clear the input list in order to store the answer. It is done to avoid the wastage of space.

Step 4: Now, display the input list on the console after storing the answer in such a way that the number that has the lesser number of set bits appears before the number that has the larger number of set bits.

Let's see the implementation of the above steps.

FileName: SetBitCntSort2.java

Output:

```For the input array:
1 4 2 8 16 64 32 128
The sorted arrange as per the set bits are:
1 4 2 8 16 64 32 128

For the input array:
11 24 7 28 128 60 132 16 5
The sorted arrange as per the set bits are:
128 16 24 132 5 11 7 28 60
```

Complexity Analysis: The time complexity of the program is O(n), as the program is using linear loops for accomplishing the task. The program is also using array lists for storing the number making the space complexity of the program O(n), where n is the total number of elements present in the input array.