# <LeetCode OJ> 326. Power of Three

8189人阅读 评论(3)

### 326. Power of Three

Total Accepted: 1159 Total Submissions: 3275 Difficulty: Easy

Given an integer, write a function to determine if it is a power of three.

Could you do it without using any loop / recursion?

a）3^x，不管x正或者负，这个值一定大于0

b）如果一个数是3的x次方那么，反复除以3，最终一定等于1，return true

c）否则不是满足要求的数,return false

class Solution {
public:
bool isPowerOfThree(int n) {
int num=n;
while(num>0 && num%3==0)
num/=3;
return num==1;
}
};

2，和上面的思想一样：递归形式的解法（题目不建议）

class Solution {
public:

bool isPow3(int n,int step) {
if(pow(3,step)==n)
return true;
if(pow(3,step)>n)
return false;
if(pow(3,step)<n)
return isPow3(n,++step);
}
bool isPowerOfThree(int n) {
int step=0;
return isPow3(n,step);
}
};

3，任何一个3的x次方一定能被int型里最大的3的x次方整除，如下所示：

return n>0?!(1162261467 % n):0;

4，或者直接列举：

class Solution {
public:
bool isPowerOfThree(int n) {
return (n == 1 || n == 3 || n == 9 || n == 27 || n == 81 || n == 243 || n == 729 || n == 2187 || n == 6561 || n == 19683 || n == 59049 || n == 177147 || n == 531441 || n == 1594323 || n == 4782969 || n == 14348907 || n == 43046721 || n == 129140163 || n == 387420489 || n == 1162261467);
}
};

5，log函数

class Solution {
public:
bool isPowerOfThree(int n) {
double res = log10(n) / log10(3);  //有精度问题，不要用以指数2.718为低的log函数
return (res - int(res) == 0) ? true : false;
}
};

Well, this problem doesn't seem to be quite interesting or worthwhile to think about at a first glance. I had the same feeling at the beginning. However, after seeing a couple of posts, I saw a couple of interesting ways. So here is a summary post and hope you learn something from others' solutions.

Two trivial solutions first:

# Recursive Solution

public boolean isPowerOfThree(int n) {
return n>0 && (n==1 || (n%3==0 && isPowerOfThree(n/3)));
}


# Iterative Solution

public boolean isPowerOfThree(int n) {
if(n>1)
while(n%3==0) n /= 3;
return n==1;
}


my original code: public boolean isPowerOfThree(int n) { while(n>1) { if(n%3!=0) return false; n /= 3; } return n<=0 ? false : true; }

Method 1

Find the maximum integer that is a power of 3 and check if it is a multiple of the given input. (related post)

public boolean isPowerOfThree(int n) {
int maxPowerOfThree = (int)Math.pow(3, (int)(Math.log(0x7fffffff) / Math.log(3)));
return n>0 && maxPowerOfThree%n==0;
}


Or simply hard code it since we know maxPowerOfThree = 1162261467:

public boolean isPowerOfThree(int n) {
return n > 0 && (1162261467 % n == 0);
}


It is worthwhile to mention that Method 1 works only when the base is prime. For example, we cannot use this algorithm to check if a number is a power of 4 or 6 or any other composite number.

Method 2

If log10(n) / log10(3) returns an int (more precisely, a double but has 0 after decimal point), then n is a power of 3. (original post). But be careful here, you cannot use log (natural log) here, because it will generate round off error for n=243. This is more like a coincidence. I mean when n=243, we have the following results:

log(243) = 5.493061443340548    log(3) = 1.0986122886681098
==> log(243)/log(3) = 4.999999999999999

log10(243) = 2.385606273598312    log10(3) = 0.47712125471966244
==> log10(243)/log10(3) = 5.0


This happens because log(3) is actually slightly larger than its true value due to round off, which makes the ratio smaller.

public boolean isPowerOfThree(int n) {
return (Math.log10(n) / Math.log10(3)) % 1 == 0;
}


Method 3 related post

public boolean isPowerOfThree(int n) {
return n==0 ? false : n==Math.pow(3, Math.round(Math.log(n) / Math.log(3)));
}


Method 4 related post

public boolean isPowerOfThree(int n) {
return n>0 && Math.abs(Math.log10(n)/Math.log10(3)-Math.ceil(Math.log10(n)/Math.log10(3))) < Double.MIN_VALUE;
}


Cheating Method

This is not really a good idea in general. But for such kind of power questions, if we need to check many times, it might be a good idea to store the desired powers into an array first. (related post)

public boolean isPowerOfThree(int n) {
int[] allPowerOfThree = new int[]{1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467};
return Arrays.binarySearch(allPowerOfThree, n) >= 0;
}


or even better with HashSet:

public boolean isPowerOfThree(int n) {
HashSet<Integer> set = new HashSet<>(Arrays.asList(1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467));
return set.contains(n);
}


# New Method Included at 15:30pm Jan-8th

The idea is to convert the original number into radix-3 format and check if it is of format 10*where 0* means k zeros with k>=0.

public boolean isPowerOfThree(int n) {
return Integer.toString(n, 3).matches("10*");
}

2
1

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：508533次
• 积分：7735
• 等级：
• 排名：第2902名
• 原创：239篇
• 转载：50篇
• 译文：0篇
• 评论：162条
博客专栏
 数据结构与算法 文章：34篇 阅读：88491
 图像处理算法 文章：22篇 阅读：90932
 LeetCode解题报告 文章：146篇 阅读：181099
 九度OJ解题报告 文章：22篇 阅读：28216
个人介绍
非CS科班出身，喜欢用C/C++思考数学 ，专注于图像处理和软件开发！本博客基于交流和记录学习的历程为目的，与诸君共勉，欢迎交流。同时，博文有不少文字并非一字一字地敲打，若侵权，请联系本人，

E-mail：tangyb7172@foxmail.com
博客内链
最新评论