319. 燈泡開關(java)

sayWhat_sayHello發表於2018-10-16

解法一(超時)

解法一會超時,但是這裡要講一下思路為正確的解法做鋪墊。

思路

當我們自己寫幾個測試用例會發現每次需要判斷只有最後一個值,也就是n的值,這個位上的燈泡到底有沒有轉換。
然而判斷這個燈泡有沒有轉換我們要看看什麼會導致他的值發生改變。
我們單純考慮一個點拿n = 9來做例子,首先第1次,第9次都會改變,然後是第3次的時候會改變。總共改變了3次所以狀態變了。
再考慮點n = 8,首先第1,8次都會改變;然後第2,4次會改變,總共改變了4次所以還是不變。
這時候考慮9以前已經改變了的值(1,4)進行累加就可以得到結果3。
下面的程式碼實現是一個時間複雜度為O(n2)的演算法。

class Solution {
    public int bulbSwitch(int n) {
        if(n == 0) return 0;
        int res = 0;
        for(int i = 1;i <= n;i++){
            if(isSwitch(i)) res++;
        }
        return res;
    }
    
    public boolean isSwitch(int n){
        int size = 0;
        for(int i = 1;i <= n;i++){
            if(n % i == 0) size++;
        }
        if(size % 2 == 1) {
            return true;
        }
        
        return false;
    }
}

解法二

通過上面的分析我們可以發現,對於n只有當 n = k2的時候才可能有奇數次轉換,否則都是偶數次。所以這時候我們對程式碼進行一點修改:時間複雜度瞬間降到O(logN)

class Solution {
    public int bulbSwitch(int n) {
        //確認 n 接近 哪個值k的平方
        if(n == 0) return 0;
        int k = 0;
        while(Math.pow(k+1,2) <= n){
            k++;
        }
        return k;
    }
}

解法三

通過呼叫jdk的方法我們可以簡化為:

class Solution {
    public int bulbSwitch(int n) {
         return (int)Math.sqrt(n);
    }
}

相關文章