LeetCode 326. Power of Three (简单题的四种求解方式)

这篇博客介绍了多种方法解决LeetCode326问题,即判断一个数是否为3的幂。包括暴力求解、优化的暴力解、数学解法(移项log)、位运算解法和质数数学性质解法。每种解法都有其独特之处,展示了数学在编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

题目链接 LeetCode 326. Power of Three

本题的标签是Math,有多种数学的实现方法,一起看看吧。

注意:文章中一切注解皆为Python代码

理解题目

题目非常简单,判断一个数是不是3的幂。

题目剖析+思考过程

最简单的方法,暴力求解,让n一直除以3,直到得到小于3的数为止。还有什么数学解法呢?显然用log也可以。那么我们先给出这两种解法,然后再看看其他新奇的解法。

代码实现(附注释)

解法一:暴力求解

太直白,就不解释了

class Solution:
    def isPowerOfThree(self, n: int) -> bool:
        while n >= 3 and n % 3 == 0:
            n //= 3
        return n == 1

解法二:暴力求解的优化

一点点优化,对于比较大的数更好用;一直在增大k(这里k=3^i,i > 0),直到不能被整除,再慢慢变回3。

class Solution:
    def isPowerOfThree(self, n: int) -> bool:
        k = 3
        while n >= 3:
            if n % k == 0:
                n //= k
                k *= 3
            elif k > 3: k //= 3
            else: return False
        return n == 1

解法三:数学解法(移项log)

如果3^k == n,那么k == log(n) / log(3),只要k是整数就说明n是3的幂

class Solution:
    def isPowerOfThree(self, n: int) -> bool:
        if n <= 0: return False
        k = log(n, 3)
        return abs(k - round(k)) < 1e-10

解法四:位运算

我们都知道,在二进制中,2的幂的表示方式都是10…0(1后面接k个0),例如:

  • 2^0 = 1 = int('1', 2)
  • 2^1 = 2 = int('10', 2)
  • 2^2 = 4 = int('100', 2)

但你可能没有去想过,这样的形式对三进制也是成立的,比如:

  • 3^0 = 1 = int('1', 3)
  • 3^1 = 3 = int('10', 3)
  • 3^2 = 9 = int('100', 3)

因此,我们只需要找出n的三进制表达式,并且判断它是否符合1后面接k个0这种模式(pattern)就可以了。

class Solution:
    def isPowerOfThree(self, n: int) -> bool:
        ans = []
        while n > 0:
            ans.append(n % 3)
            n //= 3
        return ans and ans[-1] == 1 and sum(ans[:-1]) == 0

这种方法时间复杂度和暴力解法没什么区别,上述代码甚至还要更慢一些,但是思想是非常独特的,这里就提一下。

解法五:质数的数学性质

这个方法就更另类了,我们一直都在想让n整除3取判断到底是不是3的幂,有没有想过有些数整除n也可以判断它是3的幂?

首先我们要知道,对于3^k这样一个数,它的因数全都是3的幂(1除外),因此我们只需要找到一个数3^k,并确保它大于n,在判断n是不是3^k的因数就好。

为了找到足够大的3的幂,我们可以用int(log(2**31-1, 3)),代码如下

class Solution:
    def isPowerOfThree(self, n: int) -> bool:
        return n > 0 and 3**int(log(2**31-1, 3)) % n == 0

这种解法和解法三的数学移向也没什么太大区别,但是利用底数为质数的最大幂数来求解的思想很新颖。

解题后的思考

小小的一题,有这么多种有趣的解法,每个解法各有特色,灵活运用数学才可以创造出更多有趣的解法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值