動態規劃——LeetCode264醜數 II

編寫一個程序,找出第 n 個醜數。

醜數就是隻包含質因數 2, 3, 5 的正整數。

示例:

輸入: n = 10
輸出: 12
解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
說明:  

1 是醜數。
n 不超過1690。

思考:

題解當中幾乎只有兩種思路,最小堆和dp算法(三指針)

dp解法中當前狀態不取決於前一項,而是取決於前面的項數乘以235的最小值,也即是由前面的醜數乘以235的最小值得到新的醜數,而這前面的醜數是由235三個指針確定的,初始是由1乘以235的最小值作爲第二項,隨即2因子做出了貢獻,下一個比較的對象是

2*2,1*3,1*5(3)
2*2,2*3,1*5(2)
3*2,2*3,1*5(5)
3*2,2*3,2*5(2,3)
4*2,3*3,2*5(2)
........

 Java代碼:

class Solution {
    public int nthUglyNumber(int n) {
        if ( n <= 0 ) {
            return -1;
        }
        
        //最小堆解法
        // int h[] = new int[]{2,3,5};
        // PriorityQueue<Long> pq = new PriorityQueue<>();
        // long res[] = new long[n];
        // res[0] = 1;
        // for( int i = 0 ; i < n ; i++ ) {
        //     for( int j = 0 ; j < h.length ; j++ ) {
        //         if ( !pq.contains((long)(res[i] * h[j])) ) {
        //             pq.add( (long)( res[i] * h[j]) );
        //         }
        //     }
        //     if ( i+1 < n ) {
        //         res[i+1] = pq.poll();
        //     }
        // }
        // return (int)res[n-1];

        //動態規劃三指針做法
        int dp[] = new int[n];
        dp[0] = 1;
        int i2 = 0 , i3 = 0 , i5 = 0;
        
        for( int i = 1 ; i < n ; i++ ) {
            dp[i] = Math.min( dp[i2] * 2 , Math.min( dp[i3] * 3 , 
                            dp[i5] * 5 ));
            if ( dp[i] == dp[i2] * 2 ) {
                i2++;
            }
            if ( dp[i] == dp[i3] * 3 ) {
                i3++;
            }
            if ( dp[i] == dp[i5] * 5 ) {
                i5++;
            }
        }
        return dp[n-1];
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章