题解 | #求最大连续bit数#

求最大连续bit数

http://www.nowcoder.com/practice/4b1658fd8ffb4217bc3b7e85a38cfaf2

题目的主要信息:

  • 求一个int类型数字对应的二进制数字中1的最大连续数
  • 进阶要求:时间复杂度:O(log2n)O(log_2n),空间复杂度:O(1)O(1)

方法一:连除法

具体做法:

将十进制转换成二进制的方法可以用连除取余法,那我们不断连除2,每次都取余2得到最后一位的二进制数,然后检查该二进制数是否为1,如果是1则统计计数,如果不为1说明连续中断了,比较获取最大值,并更新统计计数为0.

#include<iostream>
using namespace std;

int main(){
    int n;
    while(cin >> n){
        int count = 0; //记录每次统计的连续1的个数
        int max_count = 0; //记录最大连续1的个数
        while(n){
            if(n % 2 == 1) //最后一位为1
                count++;
            else{ //遇到不为1
                max_count = max(max_count, count); //更新最大值
                count = 0; //从0开始
            }
            n /= 2; //去掉最后一位
        }
        max_count = max(max_count, count); //最后一次更新最大值
        cout << max_count << endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(log2n)O(log_2n),连除取余一共log2nlog_2n
  • 空间复杂度:O(1)O(1),无额外空间

方法二:位运算

具体做法:

当一个数和自己左移一位进行位与运算,相当于和自己错开一位进行的位与运算,如果有连续的1,经过错位位与之后会少一个1,如果没有连续的1,错位位与之后就是0。那么我们可以通过这种不断与自己的左移一位位与,直到为0,什么时候结束就说明最大有多少连续的1。

alt

#include<iostream>
using namespace std;

int main(){
    int n;
    while(cin >> n){
        int count = 0;
        for(; n != 0; count++) //统计能够运算多少次
            n &= n << 1; //与自己左移一位后比较
        cout << count << endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(log2n)O(log_2n),平均复杂度低于上述方法一,因为不用遍历0位的情况,但是最坏复杂度还是O(log2n)O(log_2n)
  • 空间复杂度:O(1)O(1),无额外空间
孤帆远影碧空尽 文章被收录于专栏

牛客网各类题单题解~

全部评论
太秒了!!!
2 回复 分享
发布于 2022-03-02 14:44
第二方法太妙了。
2 回复 分享
发布于 2022-01-22 14:49
精妙
2 回复 分享
发布于 2022-01-09 20:21
这个位运算做法很巧妙,比直接右移(÷2)效率要快;而且试了一下,如果最高位是1时,也没有溢出问题
2 回复 分享
发布于 2021-11-29 22:44
妙妙妙,第二个方法换成右移也是一样的。
点赞 回复 分享
发布于 2023-04-17 01:21 广东
第二个方法可以用Python吗c不懂
点赞 回复 分享
发布于 2022-03-06 13:25

相关推荐

评论
54
13
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务