其他-位1的个数

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:

输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

示例 3:

输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

方法一:直接遍历数字的 32 位。如果某一位是 1 ,将计数器加一。
如何确定当前位的数字是1呢?

  • 使用与(&)运算: 1&1=1 ,1&0=0
  • 1 << 1 ,将1左移一位
num = 00000000000000000000000000001011

1 的二进制表示是
0000 0000 0000 0000 0000 0000 0000 0001
mask = 00000000000000000000000000000001

第一次比较: 
两者最后一位都是1,所以1&1=1,计数加一

比较完后,就将1左移一位
0000 0000 0000 0000 0000 0000 0000 0010
mask <<= 1
mask = 00000000000000000000000000000010

第二次比较:
都是1,所以计数加一

比较完后,将1左移一位
0000 0000 0000 0000 0000 0000 0000 0100
mask <<= 1
mask = 00000000000000000000000000000100

第三次比较:
num第三位是0,所以不计数

……

以此类推,重复此过程,把num的32位都比较一遍,就能获得答案

复杂度分析
  • 时间复杂度:O(1) 。这题中 n 是一个 32 位数,常数级别,所以运行时间是 O(1) 的。
  • 空间复杂度:O(1)。没有使用额外空间。
func hammingWeight(num uint32) int {
    //用1去和32位做与(&)运算,如果结果不是0的话 ,说明这个位置的数字就是1
    count := 0
    mask := uint32(1)
    for i:=0; i<32;i++ {
        fmt.Println(num & mask)
        if (num & mask) != 0{
            count++
        }
        //每次循环后,1的位置就向左移动一位,就像是一个指针扫描一遍这32位数一样
        mask = mask << 1
    }
    return count    
}

方法二:上面的方法,速度会稍慢些,因为每次比较都要比较32位,我们可以反向操作,将num向右移1一位,这样省了内存的同时,每次循环,比较的次数都会变少,因为num的位数每次都右移,也就是位数-1

复杂度分析
  • 时间复杂度:O(1) 。也是常数级时间复杂度。
  • 空间复杂度:O(1)。没有使用额外空间。
func hammingWeight(num uint32) int {
    count := 0
    //也可以反向操作,将num向右移1一位,这样就省了些内存
    /for num !=0 {
        if num & 1 == 1{//让num与1进行按位与运算,取得num最低位判断是否位1
            count++
        }
        num >>= 1//num右移一位
    }
    return count


}

方法三:将 n 和 n−1 做与运算,会把最后一个 1 的位变成 0

n         10100
n-1       10011
n&n-1     10000
复杂度分析
  • 时间复杂度:O(1) 。运行时间与 n 中位为 1 的有关。在最坏情况下, n 中所有位都是 1 。对于 32 位整数,运行时间是 O(1) 的。
  • 空间复杂度:O(1) 。没有使用额外空间。
func hammingWeight(num uint32) int {
    //在二进制表示中,数字 n 中最低位的 1 总是对应n−1 中的 0 。
    //因此,将 n 和 n−1 与运算总是能把 n 中最低位的 1 变成 0 ,并保持其他位不变。
    sum := 0
    for num != 0 {
        sum++
        num &= (num - 1)
    }
    return sum

}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,337评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,560评论 3 406
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,632评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,219评论 1 303
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,219评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,670评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,018评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,000评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,552评论 1 326
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,565评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,692评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,280评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,009评论 3 341
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,435评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,587评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,276评论 3 383
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,752评论 2 367

推荐阅读更多精彩内容