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^00000 0001
2^10000 0010
2^20000 0100
2^30000 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)再与原数 & 运算。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值