一、题目描述
Given an integer, write a function to determine if it is a power of three.
Example 1:
Input: 27
Output: true
Follow up: Could you do it without using any loop / recursion?
二、题解
(1) 除3判断法
/**
* @thought:找出数字 n 是否是 b 的幂数的通用做法是:n%b取余只要是0,那么一直将n/=b,
* 如果n是b的幂,那么它可以被除以x次,知道最后n==1,是1%b==1,退出循环。(即b^0==1)
* 但这不适用于负数。
* @date: 1/17/2020 2:37 PM
* @Execution info:
* ·执行用时 17 ms 击败了 27% 的java用户
* ·内存消耗 35.8MB 击败了 79% 的java用户
* @Asymptotic Time Complexity:O(log_3(n)),在我们的例子中是 O(logn)。除数是用对数表示的。
*/
public boolean isPowerOfThree1(int n) {
if(n < 1) return false;
while(n%3 == 0)
n/=3;
return n==1;
}
复杂度分析
- 时间复杂度: ,每次除以3,直到 。
- 空间复杂度: ,只使用常数级别的内存。
(2) 对数法
若 则 ,换底得 ,如果i是整数,那么n为3的幂。
- @problem:精度丢失问题,比较双精度数时不应该使用==,因为比较的结果可能是 5.0000001 或 4.9999999
- 用 Math.log() 函数而不是Math.log10() 可以观察到这种效果。
/**
* @thought:数学推导
* @date: 1/17/2020 2:46 PM
* @Execution info:
* ·执行用时 16 ms 击败了 45.22% 的java用户
* ·内存消耗 36MB 击败了 45% 的java用户
* @Asymptotic Time Complexity:O()
*/
public boolean isPowerOfThree2(int n) {
return (Math.log10(n)/Math.log10(3)) % 1 == 0;
// return (Math.log(n)/Math.log(3) + epsilon) % 1 <= 2*epsilon;
}
(3) 利用最大3的幂数
/**
* 利用最大的3次幂数1162261467对n取余是否等于0
*
* 这个最大3次幂数怎么推导出来呢?
*
* MaxInt = 2^32/2-1 == 2147483647因为我们使用 32 位来表示数字,
* 所以范围的一半用于负数,0 是正数的一部分。知道了n的上限,也就知道n的最大值
*
* 14ms,O(1)
* @param n
* @return
*/
public boolean isPowerOfThree3(int n) {
return (n > 0 && 1162261467%3==0);
}