题目描述:
Given an integer, write a function to determine if it is a power of two.
Example 1:
Input: 1 Output: true Explanation: 20 = 1
Example 2:
Input: 16 Output: true Explanation: 24 = 16
Example 3:
Input: 218 Output: false
代码实现:
方法一:用递归的方法做:
1 class Solution: 2 def isPowerOfTwo(self, n: int) -> bool: 3 if n == 1: 4 return True 5 elif n % 2 == 0 and n / 2 > 0: 6 return self.isPowerOfTwo(n/2) 7 else: 8 return False
方法二:用普通的while循环来做:
1 class Solution: 2 def isPowerOfTwo(self, n: int) -> bool: 3 while n / 2 > 0: 4 if n == 1: 5 return True 6 if n % 2 == 0: 7 n /= 2 8 else: 9 return False 10 return False
方法三(他山之石):用位运算来做:
1 class Solution: 2 def isPowerOfTwo(self, n: int) -> bool: 3 if n < 0: 4 return False 5 bin_str = bin(n) 6 return sum(map(lambda x: int(x), list(bin_str[2:]))) == 1
对方法三的分析:
python的bin()函数的用法:https://www.runoob.com/python/python-func-bin.html
python的map()函数的用法:https://www.runoob.com/python/python-func-map.html
简而言之,bin函数返回一个int型数据的二进制表示;map函数以指定的function去迭代参数序列中的每一个元素。
为什么bin_str要从第二位开始取?
答:bin函数在返回二进制表示时,第0位表示的是数的正负(0表示正,1表示负),第1位返回的是数的进制表示符(b表示二进制),从第2位开始才是真正的有效位数。
例如,以下程序的返回结果如下:
由于在程序中已经事先将负数的情况排除掉了,因此从bin函数返回结果的第2位开始取即可。
第二个return式子为什么要这样写?
答:这个表达式是基于这样一个事实:如果一个数是仅仅是由2的幂次得到的,那么它的二进制展开中必然只有一个位置是1,其他位置全是0(前提是这个数非负),而且这个1必然出现在最高位。
可以这样来理解这一事实:任何一个仅通过2的幂次得到的数,都是由二进制的1不断左移(末位不断补0而形成的),因此上述事实必然成立。
基于这一想法,程序中通过sum函数来统计二进制展开中1的个数:
如果恰好只有1个(此时这个1也必然是最高位的1),则这个数必然是2的幂次得到的数,返回True;
如果1个都没有,则说明这个数是0(负数情况已经事先排除),返回False;
如果1的个数多于1个,则这个数必然不是2的幂次得到的数,同样返回False。