2的幂

2 的幂

    • 题目
    • 解题思路
      • 直接法(更像是数学解题法)
      • 位运算
    • 提交代码
      • 直接法
      • 位运算
    • 学习总结

题目

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。

示例 1:

输入: 1
输出: true
解释: 2^0 = 1

示例 2:

输入: 16
输出: true
解释: 2^4 = 16

示例 3:

输入: 218
输出: false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/power-of-two
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

直接法(更像是数学解题法)

从原理上直接判断 2 的幂次,幂指数逐次增大,每次都与给定的整数 n 做比较,有三种情况:

  1. 小于 n:幂指数继续递增
  2. 等于 n:返回 true
  3. 大于 n:返回 false

时间复杂度为O(log N)

位运算

2 的幂次最简单体现的只是计算结果,表面上看是数学幂次运算,从过程本质上分析,基于二进制,更偏向计算机运算思维,底层的实现过程。

2的幂次 二进制表示
2^0 0000 0001
2^1 0000 0010
2^2 0000 0100
2^3 0000 1000

……

从表格中可以看出 2 的幂次二进制表示具有规律,即仅在某一位是 1 其余都是 0。于是,此题可以转化为判断给定的整数 n 的二进制表示的 1 的个数是否为一个

  • n & n - 1(去除二进制最右边的 1)
    若为 2 的幂次,如 4 ,4(0100) & 3(0011) = 0 ;对于非 2 的幂次,如 9 , 9(1001) & 8(1000) = 8(1000),不为 0 ,可区分正确结果。
  • n & -n(获得二进制最右边的 1)
    若为 2 的幂次,如 2 ,2(0010) & -2(1110) = 2(0010) ;对于非 2 的幂次,如 9 , 9(1001) & -9(0111) = 1(0001),不为 9 ,可区分正确结果。

时间复杂度为O(1)

提交代码

直接法

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        i = 0
        while i > -1:
            if pow(2,i) < n:
                i += 1
            elif pow(2,i) == n:
                return True
            else:return False

位运算

  • n & (-n)
class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        if n == 0:
            return False
        return n & (-n) == n

可简化为↓

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and n & (-n) == n
  • n & (n - 1)
class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        if n == 0:
            return False
        return n & (n - 1) == 0

可简化为↓

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        return n > 0 and n & (n - 1) == 0

学习总结

  1. 偏向数学运算的题目按照计算机处理过程来分析,更有利于问题的高效解决,解题时从思路上只考虑数学表面解法欠缺学习意义;
  2. 二进制位运算的基础应用,获取二进制最右边的 1 和去除二进制最右边的 1,分别通过相反数(-n)和减一得到(n - 1)再与原数 & 运算。

你可能感兴趣的:(逻辑运算,leetcode,python)