持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
题目描述
1356. 根据数字二进制下 1 的数目排序 - 力扣(LeetCode)
给你一个整数数组 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
思路分析
整体思路:
- 先给数组arr排序;
- 用与运算计算出每个数字在二进制下的1的数目;
- 根据二进制下的1的数目(从小到大)给每个数字进行排序; 步骤:
- 声明cnt变量, 给每个数字在二进制下的1的数目进行计数;
- 声明num变量, 在进行数字交换时使用;
- 声明temp数组, 记录每个数字在二进制下的1的数目;
- 声明index数组, 记录每个数字在arr数组中的索引值;
- 用快速排序算法给arr数组排序 (目的是为了在后面的插入排序中, 当二进制下1的数目相同时, 实现按照数值大小给数字进行升序排序);
- for循环遍历一遍排序后的数组arr, 在遍历过程中, 通过与运算计算出每个数字在二进制下的1的数目, 同时放入temp数组中;
- 使用插入排序算法对temp数组中的值进行排序, 并将排序后的值在temp数组中的索引值记录在index数组中;
- 将index数组记录的索引值替换成该索引值对应到arr数组中的值, 即将索引值替换成arr数组中的原数字;
- 最后返回index数组即可;
AC 代码
class Solution {
public int[] sortByBits(int[] arr) {
int len = arr.length;
quickSort(arr,0,len-1);//先排序
int[] temp = new int[len];//temp数组记录每个数字在二进制下的1的数目
int cnt = 0;
int num = 0;
for(int i=0;i<arr.length;i++){//for循环计算每个数字在二进制下的1的数目
cnt = 0;
num = arr[i];
while(num!=0){
cnt++;
num = num&(num-1);//与运算计算每个数字在二进制下的1的个数
}
temp[i] = cnt;
}
int[] index = new int[len];//index数组记录的是排序后, 每个数字在原数组arr中对应的索引下标
int j=0;
for(int i=0;i<len;i++){//插入排序算法, 给每个数字按照二进制下的1的个数排序
j=i;
num = temp[i];
while(j-1>=0&&temp[index[j-1]]>num){
index[j] = index[j-1];
j--;
}
index[j] = i;
}
for(int i=0;i<len;i++){//将index数组记录的索引值替换成arr数组中对应的数字
index[i] = arr[index[i]];
}
return index;
}
public void quickSort(int[] arr, int left, int right){//快速排序
int l=left;
int r=right;
int pivot = arr[(l+r)/2];
int temp = 0;
while(l<r){
while(arr[l]<pivot){
l++;
}
while(arr[r]>pivot){
r--;
}
if(l>=r){
break;
}
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
if(arr[l]==pivot){
r--;
}
if(arr[r]==pivot){
l++;
}
}
if(l==r){
l++;
r--;
}
if(left<r){
quickSort(arr,left,r);
}
if(l<right){
quickSort(arr,l,right);
}
}
}