問題:
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?
大意:
給出一個(gè)整數(shù)和措,寫一個(gè)函數(shù)來判斷它是否是3的次方數(shù)肥照。
進(jìn)階:
你能不能不用循環(huán)和遞歸來做波材?
思路:
一開始看這個(gè)題目沒明白是什么意思从藤,后來查了一下才知道是判斷是否3的次方數(shù),所謂次方數(shù)就是n個(gè)3相乘得出的數(shù)咯浸赫,總是容易想到立方上去肾请。這個(gè)題其實(shí)最簡單的就是不斷地除以3枉阵,直到結(jié)果為0,看有沒有余數(shù)技掏,有則不是铃将,沒有則是。這個(gè)做法無論是用循環(huán)還是遞歸都差不多哑梳,不過題目的進(jìn)階要求是不用循環(huán)與遞歸劲阎,這就要想辦法了。找了會(huì)規(guī)律并沒有找到鸠真,看了看別人的想法發(fā)現(xiàn)自己數(shù)學(xué)敏感性還是太差了悯仙,這直接可以轉(zhuǎn)換成求對數(shù)的計(jì)算:
n = 3^x
? log3(n) = x
要判斷給出的整數(shù)是不是3的立方數(shù),只用看x是不是整數(shù)就好了吠卷。而:
log3(n) = log10(n) / log10(3)
這里在做的時(shí)候我們直接用語言中的log函數(shù)去計(jì)算锡垄,但是要注意一點(diǎn),必須要使用log10這個(gè)函數(shù)祭隔,而不能用ln或者其他數(shù)字做底數(shù)的log函數(shù)货岭,否則在遇到243這個(gè)數(shù)字的時(shí)候會(huì)判斷錯(cuò)誤,我在這里也出了問題疾渴,這應(yīng)該是一個(gè)底層計(jì)算中的巧合千贯,在計(jì)算的時(shí)候:
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
由于我們的判斷依據(jù)是log后的結(jié)果是否是一個(gè)整數(shù),如果用其他數(shù)作為log的底數(shù)搞坝,那計(jì)算出來應(yīng)該是整數(shù)的243結(jié)果卻不是整數(shù)搔谴,因?yàn)橛?jì)算機(jī)在計(jì)算log(3)時(shí)實(shí)際上結(jié)果會(huì)稍微大一點(diǎn)點(diǎn),這就坑爹了桩撮,所以只能用log10己沛。
要判斷是不是整數(shù)很簡單,直接%1看余數(shù)是不是0就好了距境。另外別忘了還有n=0的初始情況要考慮在內(nèi)申尼。再有值得一提的就是Math并不需要額外import就可以直接使用
代碼(Java):
public class Solution {
public boolean isPowerOfThree(int n) {
return (n > 0 && (Math.log10(n) / Math.log10(3)) % 1 == 0);
}
}
代碼(C++)
#include <cmath>
class Solution {
public:
bool isPowerOfThree(int n) {
if (n <= 0) {
return false;
}
double x = log10(n) / log10(3);
if (x - (int)x == 0) return true;
return false;
}
};
合集:https://github.com/Cloudox/LeetCode-Record