8-231. Power of Two

题目描述:

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。

posted @ 2019-05-27 10:44  mingyu02  阅读(172)  评论(0编辑  收藏  举报