补充知识:二进制常见运算有与、或、异或、移位等。(参考https://blog.csdn.net/yujiubo2008/article/details/120156654

异或:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。1^0=1,1^1=0,0^0=0。

左位移(<<):a<<n表示把a转为二进制后左移n位(在后面添加 n个0)。例如100的二进制表示为1100100,100左移2位后(后面加2个0):1100100<<2 =110010000 =400,可以看出,a<<n的值实际上就是a乘以2的n次方,因为在二进制数后面添加一个0就相当该数乘以2,2个零即2的2次方,等于4。

右位移(>>):和<<相似,a>>n表示二进制右移n位(去掉末n位),相当于a除以2的n次方(取整)。

法一:循环按位比较法

#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param n int整型 
# @return int整型
#
#循环按位比较,用1循环左移位和原数字做与运算。
class Solution:
    def NumberOf1(self , n: int) -> int:
        res=0
        #遍历32位
        for i in range(32):
            #按位比较
            if (n&(1<<i))!=0:
                res=res+1
        return res

时间复杂度:O(k),k为int型的32位,一次遍历

空间复杂度:O(1),常数级变量,没有额外辅助空间

法二:

n&(n−1),会将n的二进制中最低位由1变成0。不断让当前的n与n−1做与运算【n=n&(n-1)】,直到 n的二进制全部变为 0 停止。

因为每次运算会使得n的最低位的1被翻转成0,因此累计运算次数就等于原来n的二进制位中 1 的个数。

代码参考题解区牛客题解官。

时间复杂度:O(logn),n为数字的大小,循环次数等于n的二进制位中1的个数,最坏情况下n的二进制位全部为1,也即开一个2的log运算。

空间复杂度:O(1),常数级变量,没有额外辅助空间