剑指 Offer 15. 二进制中1的个数!你不明白的都在这里?吐血整理

剑指 Offer 15. 二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

在这里插入图片描述
小试牛刀一:存取二进制

博主刚开始看到这个题时以为传进去的n是十进制所以整道题需要以下三步
1.十进制转换为二进制,存取余的值
2.倒序输出存的取余结果
3.与1比较
现在想想其实不用倒序,因为不管是正序还是倒序1的个数是确定的,因为思考到十进制转二进制需要除二取余然后倒序排列,所以博主想到了栈这个数据结构,先push进去余数,再pop出来就是我们所需的顺序。当然如果你需要输出二进制的结果一定要记得顺序,数组remainderArray存的是十进制转二进制的结果。
还要注意的是十进制转二进制时先获得余数

    public static int hamming(int n) {
        //先转为二进制,除二取余,倒序排列
        int count = 0;
        Stack<Integer> remainder = new Stack<>();
        while(n != 0){
        	//余数存入栈
            remainder.push(n%2);
            n = n/2;
        }
        int size = remainder.size();
        int[] remainderArray = new int[size];
        //出栈,遍历找为1
        for(int i = 0; i < size; i++){
            remainderArray[i] = remainder.pop();
            if(remainderArray[i] == 1){
                //使用count计数
                count++;
            }
        }
        return  count;
        //return count
    }

在执行没有通过之后博主知道放入的应该是二进制的数据,就想到将数组转换为char类型的数组,遍历数组,当与’1’同时,count++,但是这样的方法在idea会自动转换为一个是进制的数据,也是不可以得到正确的结果,在leetcode里面也得不到正确的结果,不知道为什么?

    public static int hammingWeight(int n){
        String ns = String.valueOf(n);
        char[] nc= ns.toCharArray();
        int count = 0;
        for(int i = 0; i < nc.length; i++){
            if(nc[i] == '1'){
                count++;
            }
        }
        return count;
    }

int型变量赋值为00000000000000000000000000001011不会越界吗?

并不会越界。int型变量占4个字节,一个字节8位,那么int型变量是32位的,范围是-2^31=-21 4748 3648 到 2^31-1=21 4748 3647。
int能表示的最大正整数为:
0111 1111 1111 1111 1111 1111 1111 1111 (最高位表示符号位,正数符号位为0)对应的10进制数为2^31-1=2147483647,对应的十六进制表示为:0x7FFFFFF
所以示例三的表示在idea里面会报错,超出int的范围
在这里插入图片描述

*为什么是521?

因为在数组的表示中0x表示十六进制,0表示八进制,0d表示二进制。所以00000000000000000000000000001011的八进制是521。再继续向下运算是都是按521的二进制进行运算的,521的二进制是1000001001
在这里插入图片描述

为什么下次循环是n是260?
因为& 和>>>都是二进制的运算,即1000001001的运算。&后count+1,>>>后1000001000的十进制是260
在这里插入图片描述
小试牛刀二:转换为char数组

在这里插入图片描述
为什么结果不对?
转为string类型的char[]存的是521,只会有一个1字符,这里并不清楚为什么leetcode编译出来了2,但idea编译出结果为1
在这里插入图片描述

其实在leetcode里面主要考查的是位运算符
在这里插入图片描述

方法一:逐位判断
当n&1时,末尾是0,结果是0;末尾是1,结果为1
再使用位运算将二进制后移逐位判断。

    public int hammingWeightThree(int n){
        int count = 0;
        while(n != 0){
            count += n & 1;
            n >>>= 1;
            
        }
        return count;
    }

方法二:巧用 n & (n - 1))
(n - 1) 解析: 二进制数字 n 最右边的 1变成 0,此 1右边的 00 都变成 1 。
n&(n−1) 解析: 二进制数字 n 最右边的 1变成 0 ,其余不变
.在这里插入图片描述

    public int hammingWeightTour(int n) {
        int res = 0;
        while(n != 0) {
            res++;
            n &= n - 1;
        }
        return res;
    }

方法三:调用toBinaryString()转数字符串

在Integer类中有静态方法toBinaryString(int i)方法,此方法返回int变量的二进制表示的字符串。同理,Integer类中也提供了toHexString(int i)方法和toOctalString(int i)方法来分别返回int变量的16进制表示和8进制表示字符串。

下面是调用接口直接将int数据转换为二进制字符串,即将输入00000000000000000000000000001011八进制521转为二进制再进行之后的运算。
在这里插入图片描述
方法四:replaceAll直接用null替代0

    public static int NumberOf1(int n) {
       String A =  Integer.toBinaryString(n).replaceAll("0", "");
       return A.length();
    }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值