1356. 根據數字二進位制下 1 的數目排序
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 的個數即可。
class Solution { #define N 10010 int bit[N]; public: int get(int x){ int res=0; while (x) res+=x&1,x>>=1; return res; } vector<int> sortByBits(vector<int>& arr) { for (auto x:arr) bit[x]=get(x); sort(arr.begin(),arr.end(),[&](int x,int y){ return bit[x]==bit[y]?x<y:bit[x]<bit[y]; }); return arr; } };
完整程式碼:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define N 10010
int bit[N];
int get(int x){
int res=0;
while (x)
{
res+=x&1;
x>>=1;
}
return res;
}
int cmp(const int& a,const int& b){
return bit[a]==bit[b]?a<b:bit[a]<bit[b];
}
void sortByBits(vector<int>&arr){
int len =arr.size();
sort(arr.begin(),arr.end(),cmp);
for (int i = 0; i < len; i++)
{
cout<<arr[i]<<" ";
}
}
int main(){
vector<int>vec;
int n,num;
cin>>n;
for (int i = 0; i < n; i++)
{
cin>>num;
vec.push_back(num);
bit[num]=get(num);
}
sortByBits(vec);
}
方法二:遞推預處理
我們定義 bit[i] 為數字 i 二進位制表示下數字 1 的個數,則可以列出遞推式:
bit[i]=bit[i>>1]+(i&1)
所以我們線性預處理 bitbit 陣列然後去排序即可。
class Solution { #define N 10010 int bit[N]; public: vector<int> sortByBits(vector<int>& arr) { for (int i=1;i<=10000;++i) bit[i]=bit[i>>1]+(i&1); sort(arr.begin(),arr.end(),[&](int x,int y){ return bit[x]==bit[y]?x<y:bit[x]<bit[y]; }); return arr; } };
完整程式碼:
#define N 10010 int bit[N]; int cmp(const int& a,const int& b){ return bit[a]==bit[b]?a<b:bit[a]<bit[b]; } void sortByBits(vector<int> &arr){ int len=arr.size(); for (int i = 0; i <=10000; i++) { bit[i]=bit[i>>1]+(i&1); } sort(arr.begin(),arr.end(),cmp); for (int i = 0; i < len; i++) { cout<<arr[i]<<" "; } } int main(){ vector<int>vec; int n,num; cin>>n; for (int i = 0; i < n; i++) { cin>>num; vec.push_back(num); } sortByBits(vec); }
複雜度分析
- 時間複雜度:O(nlogn)。
- 空間複雜度:O(n)。
方法三: 系統庫函式
C++ 自帶庫函式 __builtin_popcount(x) :統計 x在二進位制下的數字 1 的個數,內部實現是用查表實現的。
class Solution { #define N 10010 int bit[N]; public: vector<int> sortByBits(vector<int>& arr) { for (auto x:arr) bit[x]=__builtin_popcount(x); sort(arr.begin(),arr.end(),[&](int x,int y){ return bit[x]==bit[y]?x<y:bit[x]<bit[y]; }); return arr; } };
完整程式碼:
#include<iostream> #include<bits/stdc++.h> using namespace std; #define N 10010 int bit[N]; int cmp(const int& a,const int& b){ return bit[a]==bit[b]?a<b:bit[a]<bit[b]; } void sortByBits(vector<int> &arr){ int len=arr.size(); for (int i = 0; i <len; i++) { bit[arr[i]]=__builtin_popcount(arr[i]); } sort(arr.begin(),arr.end(),cmp); for (int i = 0; i < len; i++) { cout<<arr[i]<<" "; } } int main(){ vector<int>vec; int n,num; cin>>n; for (int i = 0; i < n; i++) { cin>>num; vec.push_back(num); } sortByBits(vec); }
複雜度分析
- 時間複雜度:O(nlogn)。
- 空間複雜度:O(n)。