1. 程式人生 > >LeetCode演算法題-Power Of Three(Java實現-七種解法)

LeetCode演算法題-Power Of Three(Java實現-七種解法)

這是悅樂書的第204次更新,第215篇原創

01 看題和準備

今天介紹的是LeetCode演算法題中Easy級別的第71題(順位題號是326)。給定一個整數,寫一個函式來確定它是否為3的冪。例如:

輸入:27
輸出:true

輸入:0
輸出:false

輸入:9
輸出:true

輸入:45
輸出:false

跟進:你可以不使用任何迴圈/遞迴嗎?

本次解題使用的開發工具是eclipse,jdk使用的版本是1.8,環境是win7 64位系統,使用Java語言編寫和測試。

02 第一種解法

新建一個變數,只要其小於n,依次乘上3,最後比較兩數是否相等。當然,你也可以做除法。

public boolean isPowerOfThree(int n) {
    long m = 1;
    while (m < n) {
        m *= 3;
    }
    return  m == n;
}


03 第二種解法

使用遞迴的方法。當n等於0的時候,返回false,當n等於1的時候,返回true。當n大於1的時候,先判斷其對3取餘是否等於 0,如果等於0,則將n除以3再呼叫自己。最後返回false。

public boolean isPowerOfThree2(int n) {
    if (n == 0) {
        return false;
    }
    if (n == 1) {
        return true;
    }
    if (n > 1) {
        return n%3 == 0 && isPowerOfThree2(n/3);
    }
    return false;
}


04 第三種解法

將第二種解法的遞迴換成迭代的方式也可以。

public boolean isPowerOfThree3(int n) {
    if (n == 0) {
        return false;
    }
    if (n == 1) {
        return true;
    }
    while (n%3 == 0) {
        n /= 3;
    }
    return n == 1;
}


05 第四種解法

利用取餘。一般的思路是對3取餘,但是這隻能判斷n是否是3的倍數,而不能保證是3的冪次方。但是我們可以反過來對n取餘,藉助1162261467這個整數,因為它是3的19次方,是int類型範圍內3能夠取到的最大冪次方數。只要n是3的冪次方,1162261467對n取餘都會返回0。

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


06 第五種解法

利用數學中的對數演算法。以下是推理步驟:

3^X == N

log (3^X) == log N

X log 3 == log N

X == (log N) / (log 3)

如果n是3的冪次方,那麼將兩數取對數後再做除法,得到的是一個以冪次方為整數位,以0位小數位的double型別數,那麼對其取整再和自身做減法,那麼它的絕對值肯定是無限接近於0的。

public boolean isPowerOfThree5(int n) {
    double lg = Math.log(n)/Math.log(3);
    return Math.abs(lg-Math.round(lg)) <= 0.00000000000001;
}


07 第六種解法

藉助包裝類Integer的toString方法。

Integer.toString(int par1, int par2),par1表示要轉成字串的數字,par2表示要轉成的進製表示。我們可以將n轉成3進位制的數,那麼只要是3的冪次方,轉換成3進位制字串後,就是一個以1開頭尾隨k個0的字串。

public boolean isPowerOfThree6(int n) {
    if (n <= 1) {
        return n == 1;
    }
    return Integer.toString(n, 3).matches("10*");
}


08 第七種解法

將int類型範圍內所有3的冪次方整數放入一個HashSet中,然後判斷n是否在HashSet中。

public boolean isPowerOfThree7(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);
}


09 小結

演算法專題目前已連續日更超過兩個月,演算法題文章71+篇,公眾號對話方塊回覆【資料結構與演算法】、【演算法】、【資料結構】中的任一關鍵詞,獲取系列文章合集。

以上就是全部內容,如果大家有什麼好的解法思路、建議或者其他問題,可以下方留言交流,點贊、留言、轉發就是對我最大的回報和支援!