剑指offer—二进制中1的个数
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路
题目要求从二进制中求出“1”的个数,首先这里要知道位移操作,当一个数向左移动
n
n
n 位时,相当于乘上
2
n
2^n
2n,为什么呢?
任何数字在计算机中都是二进制,比如
3
3
3, 二进制表示
11
11
11,指数表示
2
1
+
2
0
2^1 + 2^0
21+20
假如现在
3
3
3 向左移动一位,那么相当于给每一个有效位增加1的权重:
2
1
+
1
+
2
0
+
1
2^ {1+1}+ 2^{0+1}
21+1+20+1 =
(
2
1
+
2
0
)
∗
2
1
(2^1 + 2^0)*2^1
(21+20)∗21
由此可见
3
3
3 向左移动一位,就乘上了
2
1
2^1
21
& 读作“与”, 当两者都为1是才返回true,否则为false
将位操作和与操作相结合,我们就可以快速求出二进制中
1
1
1 的个数
假如我们现在求
5
5
5 的二进制中
1
1
1 的个数:
101
\ \ 101
101
&
1
\quad1
1
1
\quad\ \ 1
1
101
\ \ 101
101
&
10
\ \ 10
10
00
\quad00
00
101
\ \ 101
101
&
100
100
100
100
\ \ 100
100
可以看到,当
1
1
1 向左移动一位时候,右边都补上0(0&任何都为0),与数字“与”操作的,若二进制当前位为
1
1
1 ,则代表有值, 将 res + 1,这样一直遍历完 32 位(int类型)
代码
int NumberOf1(int n) {
int res = 0;
for(int i = 0; i < 32; i++){
//若当前位有 ‘1’,计数 + 1
if((1<<i)&n){
res++;
}
}
return res;
}