题目描述
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2 输出: [0,1,1] 示例 2:
输入: 5 输出: [0,1,1,2,1,2] 进阶:
给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗? 要求算法的空间复杂度为O(n)。 你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的 __builtin_popcount)来执行此操作。
来源:力扣(LeetCode) 链接: 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路分析
求二进制中1个的个数,首先,我们需要知道每个位的情况,这里我通过 共用体 + 位域 进行无消耗的二进制转换,然后通过所有位相加得到1的个数,通过循环求出所有的值
AC 代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
typedef union {
struct {
unsigned int b00 : 1, b01 : 1, b02 : 1, b03 : 1, b04 : 1, b05 : 1, b06 : 1, b07 : 1, b08 : 1, b09 : 1,
b10 : 1, b11 : 1, b12 : 1, b13 : 1, b14 : 1, b15 : 1, b16 : 1, b17 : 1, b18 : 1, b19 : 1,
b20 : 1, b21 : 1, b22 : 1, b23 : 1, b24 : 1, b25 : 1, b26 : 1, b27 : 1, b28 : 1, b29 : 1,
b30 : 1, b31 : 1;
};
unsigned int val;
} Int;
int binary32_bit_count(Int *b) {
return b->b00 + b->b01 + b->b02 + b->b03 + b->b04 + b->b05 + b->b06 + b->b07 + b->b08 + b->b09
+ b->b10 + b->b11 + b->b12 + b->b13 + b->b14 + b->b15 + b->b16 + b->b17 + b->b18 + b->b19
+ b->b20 + b->b21 + b->b22 + b->b23 + b->b24 + b->b25 + b->b26 + b->b27 + b->b28 + b->b29
+ b->b30 + b->b31;
}
int* countBits(int num, int* returnSize){
*returnSize = num + 1;
int *res = calloc(num + 1, sizeof(int));
for (int i = 0; i <= num; i++) {
res[i] = binary32_bit_count((Int *)&i);
}
return res;
}
总结
对位域和共用体的理解与使用
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情