15. 二进制中 1 的个数(剑指 Offer 题解Java版)

15. 二进制中 1 的个数

题目链接

NowCoder

题目描述

       任意给定一个32位无符号整数n,求n的二进制表示中1的个数,比如n = 5(0101)时,返回2,n = 15(1111)时,返回4

       这也是一道比较经典的题目了,相信不少人面试的时候可能遇到过这道题吧,下面介绍了几种方法来实现这道题,相信很多人可能见过下面的算法,但我相信很少有人见到本文中所有的算法。如果您上头上有更好的算法,或者本文没有提到的算法,请不要吝惜您的代码,分享的时候,也是学习和交流的时候。

思路

一. 利用Integer类的bitCount()

代码实现

package 二进制一的个数;/*
作者     :XiangLin
创建时间 :25/03/2020 23:28
文件     :BitCount1.java
IDE      :IntelliJ IDEA
*/

public class BitCount1 {
    public static int numberOfOne(int n){
        return Integer.bitCount(n);
    }

    public static void main(String[] args) {
        System.out.println("数字 10的二进制表示中的1的个数:"+numberOfOne(10));
    }
}

在这里插入图片描述

二. 常规循环

       时间复杂度O(logN)

       因为是统计1的个数,那么用输入整数的每一位与1的位与运算就可以简单的实现

代码实现

public class BitCount2 {
    public static int numberOfOne(int n){
        int result = 0;// 记录数字中1的位数
        for (int i = 0; i <= 32; i++){//int占32bit
            result += (n&1);
            n >>>= 1;
        }
        return result;
    }
    public static void main(String[] args) {
        System.out.println("数字 9的二进制表示中的1的个数:"+numberOfOne(9));//2
    }
}

在这里插入图片描述

       是最简单的方法,有点程序基础的人都能想得到,那就是移位+计数,很简单,不多说了,直接上代码,这种方法的运算次数与输入n最高位1的位置有关,最多循环32次。

public class BitCount2{
    public static int numberOfOne(int n){
        int result = 0;
        while (n > 0){
            if ((n & 1) == 1){
                ++ result;
            }
            n >>>= 1;
        }
        return result;
    }
    public static void main(String[] args) {
        System.out.println("数字 11的二进制表示中的1的个数:"+numberOfOne(11));//2
    }
}

三. n&(n-1)

       时间复杂度,其中 M 表示 1 的个数。

       一个结论
       结论:一个数与该数减一的结果进行与运算n&(n-1),会把该数右边(低位)第一个1变为0,而该位左边保持不变(高位)

       例子:比如1100(对应十进制是12),减去1之后的结果是1011(也就是十进制的11),两个数进行与运算之后,我们发现最后的结果是1000(对应十进制的8,当然这个8与后面没有关系,可以略过)。这样我们每进行一次的与运算就消去一个1,这样消到最后肯定是0了,所以我们可以在代码中以这个为循环的终止条件。

package 二进制一的个数;
/*
作者     :XiangLin
创建时间 :26/03/2020 17:51
文件     :BitCount3.java
IDE      :IntelliJ IDEA
*/

public class BitCount3 {
    public static int numberOfOne(int n){
        int result = 0;// 记录数字中1的位数

        while (n != 0){// 数字的二进制表示中有多少个1就进行多少次操作
            result ++;
            n = n&(n-1);
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println("数字 9的二进制表示中的1的个数:"+numberOfOne(9));
    }

}

在这里插入图片描述
个人微信公众号,专注于学习资源、笔记分享,欢迎关注。我们一起成长,一起学习。一直纯真着,善良着,温情地热爱生活,,如果觉得有点用的话,请不要吝啬你手中点赞的权力,谢谢我亲爱的读者朋友
五角钱的程序员,专注于学习资源、笔记分享。
Success is not something that will happen in the future, but something that will continue to accumulate from the moment you decide to do it.
成功不是将来才有的,而是从决定去做的那一刻起,持续累积而成。

2020年3月26日于重庆城口
好好学习,天天向上,终有所获

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值