跟learnjiawa一起每天一道算法编程题,既可以增强对常用API的熟悉能力,也能增强自己的编程能力和解决问题的能力。算法和数据结构,是基础中的基础,更是笔试的重中之重。
- 不积硅步,无以至千里;
- 不积小流,无以成江海。
题目描述
Java版剑指offer编程题第11题–二进制中1的个数,输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
我的想法
- 逐个判断输入整数二进制的每一位是否为1,添加一个变量作为计数器。
- 一种办法是利用 二进制数0001,0010,0100,1000,0001 0000…逐个与输入整数进行与运算,若结果不为0,则说明当前位为1。
- 另外一种办法是利用位运算每次将输入整数的二进制最右边的1变为0,不断循环,当判断最后的n变为0时,循环的次数就是二进制中1的个数。
解题方法1
public static int NumberOf1_1(int n) {
int count = 0;
int flag = 1;
while (flag != 0) {
if ((n & flag) != 0) {
count++;
}
/*这里是利用flag是int型数据,范围是[-2^31,2^31-1]
实际上当flag大于n后,后面很多比较都是没有意义的,
count一直没有变化,早就可以退出了。*/
flag = flag << 1;
}
return count;
}
解题方法2
public static int NumberOf1_2(int n) {
int count = 0;
while (n != 0) {
++count;
//这行代码的作用是将n的二进制最右边的1变为0,不影响其它位
n = (n - 1) & n;
}
return count;
}
代码测试
package com.learnjiawa.jzoffer;
/**
* @author learnjiawa
* 2019-12-10-12:03
*/
public class Solution11 {
public static void main(String[] args) {
int n = 89;
int result = NumberOf1_2(n);
System.out.println("输入整数"+n+"的二进制中1的个数为"+result);
}
public static int NumberOf1_1(int n) {
int count = 0;
int flag = 1;
while (flag != 0) {
if ((n & flag) != 0) {
count++;
}
/*这里是利用flag是int型数据,范围是[-2^31,2^31-1]
实际上当flag大于n后,后面很多比较都是没有意义的,
count一直没有变化,早就可以退出了。*/
flag = flag << 1;
}
return count;
}
public static int NumberOf1_2(int n) {
int count = 0;
while (n != 0) {
++count;
//这行代码的作用是将n的二进制最右边的1变为0,不影响其它位
n = (n - 1) & n;
}
return count;
}
}
测试代码控制台输出:
总结
题目的考察知识点是位运算,熟悉常用位运算技巧非常作用,在jdk源码中位运算技巧非常常见。
参考文献
[1]程杰. 大话数据结构. 北京:清华大学出版社, 2011.
更多
对我的文章感兴趣,点个关注是对我最大的支持,持续更新中…
关注微信公众号LearnJava: