【基础算法】二进制中1的个数问题

100 阅读4分钟

🌹作者:云小逸
📝个人主页:云小逸的主页
📝Github:云小逸的Github
🤟motto:要敢于一个人默默的面对自己,==强大自己才是核心==。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟 👏专栏:C++👏 👏专栏:Java语言👏👏专栏:Linux学习👏
👏专栏:C语言初阶👏👏专栏:数据结构👏👏专栏:备战蓝桥杯👏

@TOC


前言

今天我们继续学习算法,加油。这篇文章写的是二进制中1的个数问题。希望这篇可以有幸帮助到你,码字不易,请多多支持。 在这里插入图片描述

——————————————————————————————

AcWing 801. 二进制中1的个数

问题描述

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。

例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

算法思路

这道题目也可以称为 "求数字二进制下 1 的个数" 。我们可以通过一些二进制操作来解决这个问题,在这里简单介绍几种方法:

方法一:转化为字符串

将数字转化为字符串后,遍历字符串统计字符 '1' 的数量即可。

方法二:位运算法

假设这个数字的二进制表示中第 k 位为 1,那么将它和 1 相与的结果就是 2k-1 。我们可以每次将数字和 1 做与运算,从而得到最低位是否为 1 。然后将数字无符号右移一位,继续判断下一位是否为 1 ,直到数字变为 0 为止。

例子: 00101000 (40)进行运算时结果如下:

00101000
00000001 &   // 得到0
0010100 0>>1 // 右移之后变成了 101010
00000001 &   // 得到1
001010  0>>1 // 右移之后变成了 10101
00000010 &   // 得到0
00101   0>>1 // 右移之后变成了 1010
00000000 &   // 得到0
1010    0>>1 // 右移之后变成了 0101
00000001 &   // 得到1
010     0>>1 // 右移之后变成了 0010
00000000 &   // 得到0
001     0>>1 // 右移之后变成了 0001
00000001 &   // 得到1
000     0>>1 // 右移之后变成了 0000,最低位判断完毕。

总共有31

算法实现

方法一的 C++ 实现

int numberOf1(int n) {
    string s = to_string(n);
    int cnt = 0;
    for (auto c : s)
        if (c == '1')
            cnt++;
    return cnt;
}

方法二的 C++ 实现

int numberOf1(int n) {
    int cnt = 0;
    while (n != 0) {
        if (n & 1)
            cnt++;
        n = n >> 1;
    }
    return cnt;
}

时间复杂度分析

对于方法一,时间复杂度取决于将数字转化为字符串的复杂度,因此其时间复杂度与数字的大小和二进制表示中 1 的个数有关系。在最坏情况下,当数字为 INT_MAX 时,它的二进制表示有 31 位,其中包括了 1 个 '0' 和 30 个 '1',因此时间复杂度为 O(log n)。

对于方法二,需要执行 O(log n) 次循环来计算数字中 1 的个数,因此它的时间复杂度为 O(log n)。

总结

这道题目考察了对二进制操作的理解和应用。方法一字符串转换比较简单易懂,但是在性能上可能不如方法二。而方法二实现稍微复杂一些,但可以通过位运算来快速计算数字的二进制中 1 的个数,是一种高效的实现方式。

最后

十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:

1.把时间尺度拉长,拉长十年看当下

2.不说负面情绪,只描述事实;

3.越专注于过好自己,能量和幸运越会照顾你; 只解决问题,不做没有意义的担心,输了就认;

4.学会原谅自己,要允许自己做错事,允许自己出现情绪波动,我知道你已经很努力很努力在做好了

5.所有你害怕的、想逃避的事情,最终都要面对,既然这样不如选择坦然面对。即使结果不如人愿,没关系,至少这个过程是享受的,而不是一路带着恐惧和害怕。

最后如果觉得我写的还不错,请不要忘记==点赞==✌,==收藏==✌,加==关注==✌哦(。・ω・。)

愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚==菜鸟==逐渐成为==大佬==。加油,为自己点赞!