LC 326. 3的幂

题目描述

这是 LeetCode 上的 326. 3的幂 ,难度为 简单

给定一个整数,写一个函数来判断它是否是 $3$ 的幂次方。如果是,返回 $true$ ;否则,返回 $false$ 。

整数 $n$ 是 $3$ 的幂次方需满足:存在整数 $x$ 使得 $n == 3^x$

示例 1:

1
2
3
输入:n = 27

输出:true

示例 2:
1
2
3
输入:n = 0

输出:false

示例 3:
1
2
3
输入:n = 9

输出:true

示例 4:
1
2
3
输入:n = 45

输出:false

提示:

  • -$2^{31}$ <= n <= $2^{31}$ - 1

数学

一个不能再朴素的做法是将 $n$ 对 $3$ 进行试除,直到 $n$ 不再与 $3$ 呈倍数关系,最后判断 $n$ 是否为 $3^0 = 1$ 即可。

代码:

1
2
3
4
5
6
7
class Solution {
public boolean isPowerOfThree(int n) {
if (n <= 0) return false;
while (n % 3 == 0) n /= 3;
return n == 1;
}
}

  • 时间复杂度:$O(\log_{3}n)$
  • 空间复杂度:$O(1)$

倍数 & 约数

题目要求不能使用循环或递归来做,而传参 $n$ 的数据类型为 int,这引导我们首先分析出 int 范围内的最大 $3$ 次幂是多少,约为 $3^{19} = 1162261467$。

如果 $n$ 为 $3$ 的幂的话,那么必然满足 $n * 3^k = 1162261467$,即 $n$ 与 $1162261467$ 存在倍数关系。

因此,我们只需要判断 $n$ 是否为 $1162261467$ 的约数即可。

注意:这并不是快速判断 $x$ 的幂的通用做法,当且仅当 $x$ 为质数可用。

代码:

1
2
3
4
5
class Solution {
public boolean isPowerOfThree(int n) {
return n > 0 && 1162261467 % n == 0;
}
}

  • 时间复杂度:$O(1)$
  • 空间复杂度:$O(1)$

打表

另外一个更容易想到的「不使用循环/递归」的做法是进行打表预处理。

使用 static 代码块,预处理出不超过 int 数据范围的所有 $3$ 的幂,这样我们在跑测试样例时,就不需要使用「循环/递归」来实现逻辑,可直接 $O(1)$ 查表返回。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
static Set<Integer> set = new HashSet<>();
static {
int cur = 1;
set.add(cur);
while (cur <= Integer.MAX_VALUE / 3) {
cur *= 3;
set.add(cur);
}
}
public boolean isPowerOfThree(int n) {
return n > 0 && set.contains(n);
}
}

  • 时间复杂度:将打表逻辑交给 $OJ$ 执行的话,复杂度为 $O(\log_3{C})$,$C$ 固定为 $2147483647$;将打表逻辑放到本地执行,复杂度为 $O(1)$
  • 空间复杂度:$O(\log_3{n})$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.326 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!