LeetCode|Power of three

Power of Three

Given an integer, write a function to determine if it is a power of three.
Follow up:
Could you do it without using any loop / recursion?

ITERATIVE

If you divide the number iteratively by 3, you will get 1 at the end.

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

Alternatively, you can do it from the other direction (multiplication by three each time). But be careful of integer overflow so you have to use unsigned type or a 64-bit integer type e.g. long long.

class Solution {
public:
    bool isPowerOfThree(int n) {
        if (n <= 0) return false;
        unsigned int x = 1;
        while (x < n) {
            x *= 3;
        }
        return x == n;
    }
};

RECURSION

In the recursion form,

class Solution {
public:
    bool isPowerOfThree(int n) {
        if (n == 1) return true;
        if ((n == 0) || (n % 3 != 0)) return false;
        return isPowerOfThree(n / 3);
    }
};

CHEATING LIST

Since the input range is type of integer (32-bit signed), therefore, the valid numbers are limited and can be computed in advance. So the task is to check if the given input is in the list. You can do this using Binary Search, Linear Search, or just using hashset (e.g. unordered_set).

#include <unordered_set>

class Solution {
public:
    bool isPowerOfThree(int n) {
        std::unordered_set<int> list = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467};        
        return list.find(n) != list.end();
    }
};

MATH

From above method, we know that the biggest signed-integer (32-bit) that can be divided by 3 is 1162261467. Then we can say the any power-of-three can be divided by this number.

class Solution {
public:
    bool isPowerOfThree(int n) {
        return (n > 0) && (1162261467 % n == 0);
    }
};

LOG

We know:

3^x = n
\log(3^x) = \log(n)
x\log(3) = \log(n)
x = \log(n)/\log(3)
Therefore the value of x should be integer.

class Solution {
public:
    bool isPowerOfThree(int n) {
        double x = log(n) / log(3);
        return (n > 0) && (abs(x - (int)(x + 0.5)) < 1e-10);
    }
};

We add +0.5 to x to avoid rounding errors that is because log(243)/log(3) happens to be 4.999999999. Therefore, any math solutions that involve precision errors are not perfect. For example, the following works:

class Solution {
public:
    bool isPowerOfThree(int n) {
        double x = log10(n) / log10(3);
        return (n > 0) && (ceil(x) == floor(x));
    }
};

But, if you replace log10 function with log then it will fail the tests because of precision error from the x variable.

If you use Java, you can think of ternary number system. So any valid numbers will be in the form of 1, 10, 100, 1000 etc. Java’s Integer.toString can take a second parameter which specifies the number system you want to convert to, in this case, it is radix-3 format. The regular expression * matches zero or more characters.

public boolean isPowerOfThree(int n) {
return Integer.toString(n, 3).matches(“10*”);
}
–EOF–

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值