leetcode.1356. 根據數字二進位制下 1 的數目排序
文章目錄
題目
給你一個整數陣列 arr 。請你將陣列中的元素按照其二進位制表示中數字 1 的數目升序排序。
如果存在多個數字二進位制中 1 的數目相同,則必須將它們按照數值大小升序排列。
請你返回排序後的陣列。
示例 1:
輸入:arr = [0,1,2,3,4,5,6,7,8]
輸出:[0,1,2,4,8,3,5,6,7]
解釋:[0] 是唯一一個有 0 個 1 的數。
[1,2,4,8] 都有 1 個 1 。
[3,5,6] 有 2 個 1 。
[7] 有 3 個 1 。
按照 1 的個數排序得到的結果陣列為 [0,1,2,4,8,3,5,6,7]
示例 2:
輸入:arr = [1024,512,256,128,64,32,16,8,4,2,1]
輸出:[1,2,4,8,16,32,64,128,256,512,1024]
解釋:陣列中所有整數二進位制下都只有 1 個 1 ,所以你需要按照數值大小將它們排序。
示例 3:
輸入:arr = [10000,10000]
輸出:[10000,10000]
示例 4:
輸入:arr = [2,3,5,7,11,13,17,19]
輸出:[2,3,5,17,7,11,13,19]
示例 5:
輸入:arr = [10,100,1000,10000]
輸出:[10,100,10000,1000]
提示:
1 <= arr.length <= 500
0 <= arr[i] <= 10^4
思路
統計二進位制1
的個數可以分別獲取每個二進位制位數,然後再統計其1
的個數,此方法效率比較低。這裡介紹另外一種高效的方法,同樣以 34520
為例,我們計算其 a &= (a-1)
的結果:
第一次:計算前:1000 0110 1101 1000
計算後:1000 0110 1101 0000
第二次:計算前:1000 0110 1101 0000
計算後:1000 0110 1100 0000
第二次:計算前:1000 0110 1100 0000
計算後:1000 0110 1000 0000
我們發現,每計算一次二進位制中就少了一個 1
因此可以用此方法求1
的個數,即下面的count_one
函式。
程式碼
int count_one(int a){
int cnt=0;
while(a) a=a&(a-1),cnt++;
return cnt;
}
bool cmp(int a,int b){
int numa=count_one(a),numb=count_one(b);
return numa!=numb?numa<numb:a<b;
}
class Solution {
public:
vector<int> sortByBits(vector<int>& arr) {
sort(arr.begin(),arr.end(),cmp);
return arr;
}
};
或者
class Solution {
private:
static int count_one(int a){
int cnt=0;
while(a) a=a&(a-1),cnt++;
return cnt;
}
static bool cmp(int a,int b){
int numa=count_one(a),numb=count_one(b);
return numa!=numb?numa<numb:a<b;
}
public:
vector<int> sortByBits(vector<int>& arr) {
sort(arr.begin(),arr.end(),cmp);
return arr;
}
};
java版 ,暴力法
package sort_integers_by_the_number_of_1_bits;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Solution1 {
public int[] sortByBits(int[] arr) {
int[] bit = new int[10001];
//對每個十進位制的數轉二進位制的時候統計一下 1 的個數
List<Integer> list = new ArrayList<Integer>();
for (int x : arr) {
list.add(x);
bit[x] = get(x);
}
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
if (bit[x] != bit[y]) {
return bit[x] - bit[y];
} else {
return x - y;
}
}
});
//返回結果
for (int i = 0; i < arr.length; ++i) {
arr[i] = list.get(i);
}
return arr;
}
//對每個十進位制的數轉二進位制的時候統計一下 1 的個數
public int get(int x) {
int res = 0;
print(x);
while (x != 0) {
res += x % 2;
x /= 2;
}
return res;
}
private void print(int x) {
System.out.println("##### x="+x+" #####");
int res = 0;
while (x != 0) {
int tmp1 = x;
int tmp2 = x % 2;
res += tmp2;
System.out.printf("%5d%s%2d = %d,",tmp1," %",2,tmp2);
System.out.printf("%5d%s%2d = %d\n",tmp1," /",2,(x/=2));
}
System.out.println("res="+res);
}
public static void main(String[] args) {
int[] arr = {0,1,2,3,4,5,6,7,8,13,10000};
int[] res = new Solution1().sortByBits(arr);
System.out.println("原陣列 "+Arrays.toString(arr));
System.out.println("排序後 "+Arrays.toString(res));
}
}
輸出
##### x=0 #####
res=0
##### x=1 #####
1 % 2 = 1, 1 / 2 = 0
res=1
##### x=2 #####
2 % 2 = 0, 2 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=1
##### x=3 #####
3 % 2 = 1, 3 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=2
##### x=4 #####
4 % 2 = 0, 4 / 2 = 2
2 % 2 = 0, 2 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=1
##### x=5 #####
5 % 2 = 1, 5 / 2 = 2
2 % 2 = 0, 2 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=2
##### x=6 #####
6 % 2 = 0, 6 / 2 = 3
3 % 2 = 1, 3 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=2
##### x=7 #####
7 % 2 = 1, 7 / 2 = 3
3 % 2 = 1, 3 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=3
##### x=8 #####
8 % 2 = 0, 8 / 2 = 4
4 % 2 = 0, 4 / 2 = 2
2 % 2 = 0, 2 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=1
##### x=13 #####
13 % 2 = 1, 13 / 2 = 6
6 % 2 = 0, 6 / 2 = 3
3 % 2 = 1, 3 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=3
##### x=10000 #####
10000 % 2 = 0,10000 / 2 = 5000
5000 % 2 = 0, 5000 / 2 = 2500
2500 % 2 = 0, 2500 / 2 = 1250
1250 % 2 = 0, 1250 / 2 = 625
625 % 2 = 1, 625 / 2 = 312
312 % 2 = 0, 312 / 2 = 156
156 % 2 = 0, 156 / 2 = 78
78 % 2 = 0, 78 / 2 = 39
39 % 2 = 1, 39 / 2 = 19
19 % 2 = 1, 19 / 2 = 9
9 % 2 = 1, 9 / 2 = 4
4 % 2 = 0, 4 / 2 = 2
2 % 2 = 0, 2 / 2 = 1
1 % 2 = 1, 1 / 2 = 0
res=5
原陣列 [0, 1, 2, 4, 8, 3, 5, 6, 7, 13, 10000]
排序後 [0, 1, 2, 4, 8, 3, 5, 6, 7, 13, 10000]
相關文章
- 根據數字二進位制下 1 的數目排序排序
- 力扣 根據數字二進位制下1的數目排序力扣排序
- leetcode-1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- leetcode1356. 根據數字二進位制下 1 的數目排序LeetCode排序
- 力扣1356.根據數字二進位制下1的數目排序力扣排序
- 二進位制中1的個數
- 二維陣列根據欄位進行排序陣列排序
- SpringJpa @query 中根據傳入引數(欄位)排序Spring排序
- 根據介面返回的二進位制流匯出檔案
- 頁面顯示二進位制數原始據亂碼
- 負數的二進位制數問題
- C++輸入十進位制數,輸出對應二進位制數、十六進位制數C++
- 【劍指offer】二進位制中1的個數
- JZ-011-二進位制中 1 的個數
- 1417 二進位制數的大小
- 輸出二進位制數
- 根據字典,轉成相應的進位制
- 驗證二進位制數字正規表示式
- 【刷演算法】二進位制中1的個數演算法
- 二維陣列根據某個欄位排序陣列排序
- 劍指 Offer 15. 二進位制中1的個數
- 整數轉化成八進位制、十六進位制、二進位制,以及轉回
- 二維陣列根據鍵的值進行排序陣列排序
- 對十進位制數字的按位輸出,取反,並求其位數
- 牛客網測試題 把十六進位制數字轉換為十進位制數字
- 一看就懂二進位制、八進位制、十六進位制數轉換十進位制
- leedcode-數字轉換為十六進位制數
- 二進位制漏洞挖掘之整數溢位
- 教你如何進行數倉字串、二進位制、十六進位制互轉字串
- 對陣列中的數字 1 和 2 進行排序,使得數字 1、2 分別位於前、後部分陣列排序
- 負數補碼(16進位制轉10進位制的負數)
- 使用 Haskell 將十進位制數字轉成羅馬數字Haskell
- 【proto】python根據proto檔案構造message,並換為二進位制Python
- 如何把十進位制的數輸入用二進位制全加器,並以十進位制輸出
- offer通過--10二進位制中統計1的個數-2
- 【劍指offer中等部分4】二進位制中1的個數(java)Java
- 牛客網 二進位制數(進位制轉換、北郵機試)
- 任意進位制下的可逆素數 C++C++