题目描述
给定一个32位的无符号整数(unsigned integer),求出有几位值为1。貌似这个问题也被称做Hamming weight,anyway,下面来说一下怎么解决这个问题。
思路一
是我自己的解法,思路很简单,就是通过对每一位依次进行&1运算,如果结果返回1,则当前位也就位1。下面是python代码。
def hammingWeight_s1(n):
"""
:type n: int
:rtype: int
"""
count=(n&1)
for i in range(31):
n=n>>1 #每次右移一位
count+=(n&1)
return count
思路二
这一种想法就不那么直接了,是我在看别人的答案时发现的一种十分巧妙的解法。他的想法是对于一个无符号整数,下界为0。然后,如果对当前整数-1,比如当前的n=100100,那么-1后就变为n-1=100011。此时如果我们对n和n-1进行&运算,那么结果就是n&(n-1)=100000。发现了吗,通过比较n和n&(n-1),我们的发现当前n的最右边存在的一位1被消去了。也就是说通过循环进行这个操作,每次都会消去当前n最右边的一位1,直到到达最小值0。换句话说,在n变为0前,进行几次这个操作,就代表最初的n有几个1!代码也十分容易写,如下。
def hammingWeight_s2(n):
count=0
while n:
n=n&(n-1)
count+=1
return count
两种方法的时间复杂度比较
第一种方法,毫无疑问的,时间复杂度为O(n),对于第二种方法,复杂度取决于具体数中的1的个数,如果有m位1,那么其复杂度就为O(m),但是无论如何是会小于第一种方法,但是提交结果给的反馈却是第一种方法的速度更快,我想可能是第二种方法在单次循环内的计算量更大造成的。