题目描述:
给一个数组arr,根据arr中数字的二进制中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]
输出:[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]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits
链接:https://leetcode-cn.com/problems/sort-integers-by-the-number-of-1-bits
代码如下:
1 def sortbin(arr): 2 bin_num = [] # 存储bin_arr二进制数中1的个数 3 for i in arr: 4 count = 0 5 while i: 6 i &= i - 1 7 count = count + 1 8 bin_num.append(count) 9 10 temp = [[] for i in range(510)] 11 # 将arr中具有相同二进制位数的数放在一起 12 for i in range(len(bin_num)): 13 temp[bin_num[i]].append(arr[i]) 14 15 reslut = [] 16 for i in temp: 17 # 对具有相同二进制位数进行大小排序 18 i.sort() 19 if i: 20 reslut.extend(i) 21 else: 22 continue 23 24 return reslut 25 26 27 print("---------------测试sortbin()-------------") 28 arr = [1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1] 29 reslut = sortbin(arr) 30 print("result=", reslut) 31 32 33 def sortbin1(arr): 34 def count_bin(x): 35 return bin(x).count('1') 36 37 reslut = sorted(arr, key=lambda x: (count_bin(x), x)) 38 39 return reslut 40 41 42 print('++++++++++++测试sortbin1()++++++++++++++') 43 reslut = sortbin1(arr) 44 print('result=', reslut)
输出如下:
---------------测试sortbin()------------- result= [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] ++++++++++++测试sortbin1()++++++++++++++ result= [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
总结:
比较两种方法,很明显方法2要简洁的多,代码质量更高。在方法1中,整体思路是求出arr数组中各数字1的个数,并将具有相同数目的元素放在一起,组成新的数组,遍历该数组,对该数组中各元素按数字大小排序,然后将各元素加入到结果数组中即可。因此方法1需要考虑两个问题。第一:如何求出arr数组中各数字的二进制?第二:对求出的二进制,如何统计1的个数并将具有相同数目1的元素放在一起?上面代码一一给出了解答。
方法2中,代码清晰简洁。定义了一个嵌套函数用来统计数字二进制中1的数目,然后在排序过程中采用lambda表达式,排序的两个主次限制条件分别为二进制位数和数字大小
加强理解的地方:方法1中二进制位数求取方法:num&=num-1。num和num-1相与至0的次数即为num二进制位数。sort()方法和sorted()方法区别,sort()方法排序后没有返回新的对象,它是对当前调用对象进行了排序,返回的还是当前对象;sorted()方法返回了新对象,原调用对象没发生变化。