动态规划——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];
    }
}

 

posted @ 2019-11-16 18:54  great978  阅读(147)  评论(0编辑  收藏  举报