题目信息
题目地址:https://leetcode-cn.com/problems/power-of-three
给定一个整数,写一个函数来判断它是否是3 的幂次方。如果是,返回 true ;否则,返回 false 。整数 n 是 3 的幂次方需满足:存在整数 x 使得 n == 3^x
示例1:
输入:n = 27
输出:true
示例2:
输入:n = 0
输出:false
示例3:
输入:n = 9
输出:true
示例4:
输入:n = 45
输出:false
提示:
- -2^31 <= n <= 2^31 - 1
进阶:
- 你能不使用循环或者递归来完成本题吗?
题解一:迭代
看到这题第一想法就是循环降幂(除3)一直可以到最终0次幂也就是等于1说明它是3的幂。
public boolean isPowerOfThree(int n) {
if(n <= 0) return false;
while(n != 1){
if(n%3 == 0){
n = n/3;
}else{
return false;
}
}
return true;
}
image-20210829132225200
这个倒是挺顺利一次过,没有太多细节。时间复杂度规模每次是在上一次除三所以是log以3为底的次数,也就是O(logn)。空间上连变量都没有用,O(1)
题解二:数字范围
那在题目提示上说可以不用循环来去做,循环这种它是基本的推演逻辑。现在应该是对于数字上它是否有什么规律,是否有总结公式这样去考虑。最后是参考了官解,主要有两点:
- 一个质数的幂次方,他的因数只会是这个质数的幂次方
- 参数n的范围
根据这两点是可以知道,从参数n的范围找到一个最大的3的幂次方max3。那么所有的幂次方都是可以被这个最大的max3整除。不能被max3整除的它就不是3的幂次方。
这里可以推演一下,用底数2来。假设指定n的范围是100以内。传入一个n判断它是不是2的幂次方?
一百以内的2的幂次方有:
1 2 4 8 16 32 64
传入一个n怎么判断是2的幂次方呢?
也就是怎么判断是上面这些数之一呢?
用64去除即可,
它除上面这些数都可以整除,
一百内其他的都没办法被64整除
是因为质数是最小因数
回到题目,这里n最大是int类型的最大也就是2^31 - 1,那么在这个范围里面3^19(1162261467)是最大的3的幂次方。传入的n只要能被3^19整除那么它就是3的幂次方
public boolean isPowerOfThree(int n) {
if(n <= 0) return false;
return 1162261467%n == 0;
}
image-20210829142205811
这个不用说时间与空间复杂度都是O(1)
总结
这道题的话其实解法一效率就很高了,在官方题解里是有还有一种通过转换进制判断除了最高位之外其他位是否为0来判断它是否是幂集里,这种就是效率很低的偏离了解题走了弯路。大多情况下解法一与解法二效率差不多,但在数量级较大解法二会优一点。解法二的诞生利用隐藏特性,锁定范围进而减少解题步骤。无论是对于程序算法还是单纯的数学题,在解题之前确实需要尽量详尽的列出题目信息当中包含的所有已知条件,全部利用上才能给出当下这个场景下最好的最针对的解。
扫码二维码
获取更多精彩
coding