
Problem Statement
In this task, you need to sort an array of integers, but not in the usual way. Each integer should be considered in terms of its binary form, and specifically, by the number of '1's it features when expressed in binary. The main sorting criterion is the quantity of '1's in each number's binary expression. In cases where multiple integers have an identical number of '1's, these numbers should be further sorted by their value in increasing order. The goal is to return the array after applying this dual sorting methodology.
Examples
Example 1
Input:
arr = [0,1,2,3,4,5,6,7,8]
Output:
[0,1,2,4,8,3,5,6,7]
Explantion:
[0] is the only integer with 0 bits. [1,2,4,8] all have 1 bit. [3,5,6] have 2 bits. [7] has 3 bits. The sorted array by bits is [0,1,2,4,8,3,5,6,7]
Example 2
Input:
arr = [1024,512,256,128,64,32,16,8,4,2,1]
Output:
[1,2,4,8,16,32,64,128,256,512,1024]
Explantion:
All integers have 1 bit in the binary representation, you should just sort them in ascending order.
Constraints
1 <= arr.length <= 5000 <= arr[i] <= 104
Approach and Intuition
The problem can be approached by breaking down the solution into simpler steps:
- Translate each integer into its binary form and determine the number of '1's it contains. This operation is at the heart of our sorting mechanism.
- Sort the array primarily by the count of '1's in the binary representations. Where two integers have an equal count, the sorting will revert to using the integer values themselves for a secondary sort.
- Construct the sorted list based on these criteria and return it.
To clarify with examples:
Example 1: Consider
arr = [0,1,2,3,4,5,6,7,8]. Once we calculate the binary representation:0converts to0in binary (0ones).1,2,4, and8convert to1,10,100, and1000respectively (all having1one).3,5, and6convert to11,101, and110respectively (2ones).7converts to111(3ones). The required sorted order based on the bit count and values hence would be[0,1,2,4,8,3,5,6,7].
Example 2: For
arr = [1024,512,256,128,64,32,16,8,4,2,1], each number is a power of2and thus contains only one1in its binary form. Therefore, the sorting criteria defaults to their actual numerical values in ascending order which remains as[1,2,4,8,16,32,64,128,256,512,1024].
These examples illuminate how the approach works in different scenarios, leading to the comprehensive understanding necessary to program a solution effectively.
Solutions
- C++
class Solution {
public:
static int calculateWeight(int number) {
int sum = 0;
while (number > 0) {
sum++;
number &= (number - 1);
}
return sum;
}
static bool customSort(int x, int y) {
int wx = calculateWeight(x);
int wy = calculateWeight(y);
if (wx == wy) return x < y;
return wx < wy;
}
vector<int> sortByBits(vector<int>& values) {
sort(values.begin(), values.end(), customSort);
return values;
}
};
This article summarizes the solution to the problem of sorting integers by the number of 1 bits found in their binary representation, using C++ as the programming language. The implementation is within a class named Solution.
Implement a helper function
calculateWeightwhich counts the number of 1 bits in the binary form of its input, usingnumber &= (number - 1)to clear the least significant 1 bit on each iteration.Define another function
customSort, which compares two integers based on their 1-bit count (calculated by callingcalculateWeight). If two integers have the same count, they are sorted by their value.Define the
sortByBitsfunction inside the Solution class. This function uses thesortfunction from the C++ Standard Library. It employscustomSortas its comparison function.The
sortByBitsfunction receives a vector of integers, sorts them using the defined criteria, and returns the sorted vector.
Ensure the given C++ code is properly implemented with thorough tests to handle varied input cases, and validate results to ensure accuracy in sorting based on the count of 1-bits, with secondary sorting by integer values in case of ties.
- Java
class Solution {
public int[] sortOnBitCount(int[] array) {
Integer[] integers = Arrays.stream(array).boxed().toArray(Integer[]::new);
Comparator<Integer> bitComparator = new BitBasedComparator();
Arrays.sort(integers, bitComparator);
return Arrays.stream(integers).mapToInt(Integer::intValue).toArray();
}
}
class BitBasedComparator implements Comparator<Integer> {
private int calculateBitWeight(int number) {
int count = 0;
while (number > 0) {
count++;
number &= (number - 1);
}
return count;
}
@Override
public int compare(Integer x, Integer y) {
if (calculateBitWeight(x) == calculateBitWeight(y)) {
return x - y;
}
return calculateBitWeight(x) - calculateBitWeight(y);
}
}
The provided Java solution addresses the problem of sorting an array of integers based on the number of 1 bits they contain, with ties broken by the values of the integers themselves. Here's a breakdown of how the solution works:
Conversion of Primitive Array: The solution starts by converting the primitive
intarray to anIntegerarray using Java Streams. This conversion is essential because theArrays.sort()method in Java uses aComparator, which can only be applied to objects, not primitives.Custom Comparator: A custom comparator,
BitBasedComparator, is created for sorting. This comparator defines the sorting behavior based on the bit count of the integers. Thecomparemethod of this comparator calculates the number of 1s in the binary representation of each integer using thecalculateBitWeightmethod, which employs Brian Kernighan's algorithm to efficiently count the number of 1 bits.Sorting Process: The
Arrays.sort()method is employed, using the custom comparator to rank the integers. After sorting, theIntegerarray is converted back to a primitiveintarray to maintain the original data type consistency.Counting 1s in Binary Representation: The
calculateBitWeightfunction iteratively counts the bits by continuously stripping the lowest set bit using the expressionnumber &= (number - 1)until all bits are zeroed out. Each operation effectively removes the lowest set bit, and the count of these operations is the bit weight.
This solution efficiently sorts the integers using bit counts, providing a direct way to organize data based on binary characteristics which can be advantageous in various applications such as optimization algorithms, cryptographic functions, or memory management systems, where understanding bit-level data can be crucial.
- Python
class Solution:
def bitSort(self, arr: List[int]) -> List[int]:
def bit_weight(x):
count = 0
while x:
count += 1
x &= x - 1
return count
arr.sort(key=lambda x: (bit_weight(x), x))
return arr
Sort integers by the number of 1 bits in their binary representation using Python. This example employs a custom sorting strategy.
First, define a function bit_weight that calculates the number of 1's in the binary representation of an integer. This function utilizes a bitwise operation where the integer is continually bitwise ANDed with its immediate predecessor, incrementing a counter until the integer becomes zero.
Next, sort the array with a key that uses a lambda function. The lambda function sorts primarily by the count of 1 bits (computed via bit_weight), and secondarily by the integer's value itself in cases where multiple integers have the same number of 1 bits. This dual sorting ensures a stable and accurate sort order.
The steps involved in sorting the integers in the list arr by the number of 1 bits are as follows:
- Define the
bit_weighthelper function to count the number of 1's for any given integer. - Use the
sortmethod on the array, specifying a lambda function as the key that appliesbit_weightto each element for primary sorting and defaults to the integer's value for tie-breaking.
This method provides a straightforward approach to sorting where binary properties of numbers are considered, beneficial in various applications such as coding challenges or data processing tasks where binary representations are crucial.