剑指offer——15.二进制中 1 的个数——分析及代码[Java]
一、题目
输入一个整数,输出该数二进制表示中 1 的个数,其中负数用补码表示。
二、分析及代码
1. 各位依次判断
(1)思路
判断二进制中 1 的个数,可以通过将输入整数的各个位置依次与仅该位置为 1 的二进制数作与运算进行。
若对整数进行右移,当输入的整数为负数时,最高位会自动补 1,给统计带来不便,因此选择将用于比较的二进制数进行左移。
需要注意的是,每次比较完成后,应通过判断比较的结果是否不为 0,决定答案是否 +1,消除数位的影响,而不可直接相加。(例如,当对第 2 位进行比较时,若结果不为 0,与运算得到的数值是 10,直接相加会导致结果添加了 10)。
这种方法循环的次数取决于整数二进制的位数。
(2)代码
public class Solution {
public int NumberOf1(int n) {
int flag = 1, ans = 0;
while (flag != 0) {
if ((n & flag) != 0)
ans++;
flag = flag << 1;
}
return ans;
}
}
(3)结果
运行时间:17ms,占用内存:9364k。
2. 更高效的算法
(1)思路
通过分析可以得到,当一个二进制数和 -1 后的该数作与运算时,相当于将该二进制数的最右边的 1 变为 0。
因此,可以对输入的二进制数不断与 -1 后的该数作与运算,当数字变为 0 时,运算的次数就是原输入数据二进制表示中 1 的个数。
(2)代码
public class Solution {
public int NumberOf1(int n) {
int ans = 0;
while (n != 0) {
n = n & (n - 1);
ans++;
}
return ans;
}
}
(3)结果
运行时间:12ms,占用内存:9432k。
三、其他
暂无。