【攻克剑指offer】第4天《二进制中1的个数》


题目描述: 💦
在这里插入图片描述

👉题目链接👈

🏠解法一、位数检查

首先我们先了解一下与运算

若 n & 1 = 0,则 n 二进制 最右一位 为0 ;
若 n & 1 = 1,则 n 二进制 最右一位 为1

思路分析: 💫

一个朴素的做法,对 int 的每一位进行检查,并统计 1 的个数。

代码展示: 👇

public class Solution {
    public int hammingWeight(int n) {
        int ans = 0;
        for (int i = 0; i < 32; i++) {
            ans += ((n >> i) & 1);
        }
        return ans;
    }
}

以上算法实现的复杂度分析:

  • 时间复杂度是: O(k),k 为 int 的位数,固定为 32 位
  • 空间复杂度是 : O(1)

🏠解法二、右移统计

思路分析: 💫

1.判断 n 最右一位是否为 1 ,根据结果计数。
2.将 n 右移一位(本题要求把数字 n 看作无符号数,因此使用无符号右移操作)

代码展示: 👇

public class Solution {
    public int hammingWeight(int n) {
        int res = 0;     //初始化数量统计变量 res = 0
        while(n != 0) {   //循环逐位判断:当 n = 0 时跳出
            res += n & 1;   //若n & 1 = 1 ,则统计数 resres 加一
            n >>>= 1;   //Java 中无符号右移为 ">>>" 
        }
        return res;
    }
}

🏘️解法三、巧用

经过解法一和解法二我们又可以发现一个更简单的方法

思路分析: 💫

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

代码展示: 👇

public class Solution {
    public int hammingWeight(int n) {
        int res = 0;     //初始化数量统计变量 res
        while(n != 0) {    
            res++;      //统计变量加 1
            n &= n - 1;    //消去数字 n 最右边的 1
        }
        return res;
    }
}

以上算法实现的复杂度分析:

  • 时间复杂度是: O(M)),n&(n−1) 操作仅有减法和与运算,占用 O(1);设 M 为二进制数字 n 中 1 的个数,则需循环 M 次(每轮消去一个 1 ),占用 O(M)。
  • 空间复杂度是 : O(1),变量 res使用常数大小额外空间。

相关文章:
上一篇:【剑指offer】之《斐波那契数列》
下一篇:【剑指offer】之《在排序数组中查找数字》

🌈我的感受:

  如果对操作符的运算理解的不错的话这道题难度应该也不大,我这三种方法其实也只算一种方法不断优化而来,还有几种方法我看了一下没整明白,等我学会补上。加油,如果你选择开始刷题就要选择坚持下去,给你打气~
在这里插入图片描述

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小奕vi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值