1356. Sort Integers by The Number of 1 Bits
Description
You are given an integer array arr. Sort the integers in the array in ascending order by the number of 1's in their binary representation and in case of two or more integers have the same number of 1's you have to sort them in ascending order.
Return the array after sorting it.
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
Solutions
Solution 1: Custom Sorting
We sort the array $arr$ according to the requirements of the problem, that is, sort in ascending order according to the number of $1$s in the binary representation. If there are multiple numbers with the same number of $1$s in the binary representation, they must be sorted in ascending order by numerical value.
The time complexity is $O(n \log n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array $arr$.
Python3
class Solution:
def sortByBits(self, arr: List[int]) -> List[int]:
return sorted(arr, key=lambda x: (x.bit_count(), x))
Java
class Solution {
public int[] sortByBits(int[] arr) {
int n = arr.length;
for (int i = 0; i < n; ++i) {
arr[i] += Integer.bitCount(arr[i]) * 100000;
}
Arrays.sort(arr);
for (int i = 0; i < n; ++i) {
arr[i] %= 100000;
}
return arr;
}
}
C++
class Solution {
public:
vector<int> sortByBits(vector<int>& arr) {
for (int& v : arr) {
v += __builtin_popcount(v) * 100000;
}
sort(arr.begin(), arr.end());
for (int& v : arr) {
v %= 100000;
}
return arr;
}
};
Go
func sortByBits(arr []int) []int {
for i, v := range arr {
arr[i] += bits.OnesCount(uint(v)) * 100000
}
sort.Ints(arr)
for i := range arr {
arr[i] %= 100000
}
return arr
}
TypeScript
function sortByBits(arr: number[]): number[] {
const countOnes = (n: number) => {
let res = 0;
while (n) {
n &= n - 1;
res++;
}
return res;
};
return arr.sort((a, b) => countOnes(a) - countOnes(b) || a - b);
}
Rust
impl Solution {
pub fn sort_by_bits(mut arr: Vec<i32>) -> Vec<i32> {
arr.sort_by(|a, b| {
let res = a.count_ones().cmp(&b.count_ones());
if res == std::cmp::Ordering::Equal {
return a.cmp(&b);
}
res
});
arr
}
}
C
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int countOnes(int n) {
int res = 0;
while (n) {
n &= n - 1;
res++;
}
return res;
}
int cmp(const void* _a, const void* _b) {
int a = *(int*) _a;
int b = *(int*) _b;
int res = countOnes(a) - countOnes(b);
if (res == 0) {
return a - b;
}
return res;
}
int* sortByBits(int* arr, int arrSize, int* returnSize) {
qsort(arr, arrSize, sizeof(int), cmp);
*returnSize = arrSize;
return arr;
}
Solution 2
Java
class Solution {
public int[] sortByBits(int[] arr) {
int n = arr.length;
Integer[] t = new Integer[n];
for (int i = 0; i < n; ++i) {
t[i] = arr[i];
}
Arrays.sort(t, (a, b) -> {
int x = Integer.bitCount(a), y = Integer.bitCount(b);
return x == y ? a - b : x - y;
});
for (int i = 0; i < n; ++i) {
arr[i] = t[i];
}
return arr;
}
}
C++
class Solution {
public:
vector<int> sortByBits(vector<int>& arr) {
sort(arr.begin(), arr.end(), [&](auto& a, auto& b) -> bool {
int x = __builtin_popcount(a), y = __builtin_popcount(b);
return x < y || (x == y && a < b);
});
return arr;
}
};
Go
func sortByBits(arr []int) []int {
sort.Slice(arr, func(i, j int) bool {
a, b := bits.OnesCount(uint(arr[i])), bits.OnesCount(uint(arr[j]))
return a < b || (a == b && arr[i] < arr[j])
})
return arr
}