LeetCode 338比特位计数
300 Words|Read in about 2 Min|本文总阅读量次
leetcode第338题,比特位计数。采用位运算或者奇偶性来完成。
LeetCode 338比特位计数
给你一个整数 n
,对于 0 <= i <= n
中的每个 i
,计算其二进制表示中 1
的个数 ,返回一个长度为 n + 1
的数组 ans
作为答案。
示例 1:
1输入:n = 2
2输出:[0,1,1]
3解释:
40 --> 0
51 --> 1
62 --> 10
示例 2:
1输入:n = 5
2输出:[0,1,1,2,1,2]
3解释:
40 --> 0
51 --> 1
62 --> 10
73 --> 11
84 --> 100
95 --> 101
提示:
0 <= n <= 105
进阶:
- 很容易就能实现时间复杂度为
O(n log n)
的解决方案,你可以在线性时间复杂度O(n)
内用一趟扫描解决此问题吗? - 你能不使用任何内置函数解决此问题吗?(如,C++ 中的
__builtin_popcount
)
思路
使用位运算。
1//清除最低位的1
2x = x & (x - 1)
15跟14相比相差最低位的1
14跟12相比相差最低位的1
12跟8相比相差最低位的1
8跟0相比相差最低位的1
也就是说实际上15位中有几个1,可以是等价于14位中有几个1再加上1;同理14位中有几个1,可以是等价于12位中有几个1再加上1;12位中有几个1,可以是等价于8位中有几个1再加上1;8位中有几个1,可以是等价于0位中有几个1再加上1。
解题
1class Solution {
2 public int[] countBits(int n) {
3 int[] bitArray = new int[n + 1];
4 //初始值为0
5 bitArray[0] = 0;
6 for(int i = 1; i < n + 1; i++)
7 {
8 //有递归的思想
9 bitArray[i] = bitArray[i & (i - 1)] + 1;
10 }
11 return bitArray;
12 }
13}
思路2
可以用奇偶的特性
1//当奇数的时候
2//9 1001
3//8 1000
4bitArray[i] = bitArray[i - 1];
5//当偶数的时候
6//例如
7//8 1000
8//4 0100
9//2 0010
10//1 0001
11bitArray[i] = bitArray[i >> 1];
解题
1class Solution {
2 public int[] countBits(int n) {
3 int[] bitArray = new int[n + 1];
4 //初始值为0
5 bitArray[0] = 0;
6 for(int i = 1; i < n + 1; i++)
7 {
8 //使用奇偶性
9 bitArray[i] = ((i & 1) == 1) ?
10 bitArray[i - 1] + 1 :
11 bitArray[i >> 1];
12 }
13 return bitArray;
14 }
15}