题目描述#
哎呀,这题名字怪可爱的——“位 1 的个数”。给你一个正整数 n,把它写成二进制后,数一数里头有多少个 1,返回这个数量就行。这个值还有个学名叫汉明重量(Hamming Weight)。
思路#
咱第一眼看,这题就是"逐位检查"的活儿:把 n 的二进制位一个个看过去,是 1 就记一笔。
每一轮干两件事:
n & 1 == 1:用按位与取出n当前的最低位,要是它等于1,计数器ans加一。n = n >> 1:把n右移一位,丢掉刚看过的最低位,让下一位顶上来。
循环条件是 n != 0——只要 n 还有没处理完的位(也就是还没全变成 0)就接着数。这样比死板地循环 32 次更省,遇上 n 很小的时候,高位全是 0 就不用白跑了。本姑娘试过最朴素的解法,思路简单到一看就懂,可它就是稳~
对了,还有个更"耍帅"的写法叫
n & (n-1)——这一步能直接把最低位的那个1抹掉,所以循环几次就说明有几个1,循环次数只跟1的个数挂钩。咱这版走的是逐位扫描,更直白;那个技巧留着下次拆开细讲~
知识边界#
- 取最低位:
n & 1拿到二进制最末位(0 或 1),判断这一位是不是1。 - 右移推进:
n >> 1丢掉已检查的最低位。注意这题语境是正整数 / 无符号位,右移时高位补 0,循环能正常终止;要是负数在某些语言里算术右移会补 1,可能死循环——这点容易踩坑哦。 - 循环条件
n != 0:比固定循环 32 次更省,提前在高位全 0 时收工。 - 进阶技巧
n & (n-1):每次清除最低位的1,循环次数 =1的个数,是数 set bit 的经典优化(本题没用,作了解)。
代码#
下面这版咱一行没动,逐位扫描数 1:
func hammingWeight(n int) int {
ans := 0
for n != 0 {
if n&1 == 1 {
ans++
}
n = n >> 1
}
return ans
}好啦,位运算章节又添一道~咱去拍张照存个档,下次再来收拾更刁钻的位操作题!