【LeetCode】313. 超级丑数

313. 超级丑数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法:“多路归并”

思路

  • 这道题其实是 264. 丑数 II 的进阶,前者固定使用三个指针,分别对应于 2、3、5,而这道的primes数组长度不固定,因此使用指针数组来对应 primes 的每一个值。

  • 第一个丑数一定是 1,而「往后产生的丑数」都是基于「已有丑数」而来(使用「已有丑数」乘上「给定质因数」primes[i] )。具体过程如图所示。

    【LeetCode】313. 超级丑数_第1张图片

    • 显然,我们需要每次取值最小的一个,然后让指针后移(指向下一个丑数),不断重复这个过程,直到找到第 n 个丑数。
    • 另外,由于我们每个指针移动和 dp的构造,都是单调递增,因此可以通过与 dp[i-1] 进行比较来实现去重,而无须引用 Set 结构。

代码

class Solution {
public:
    long nthSuperUglyNumber(int n, vector<int>& primes) {
        int len = primes.size();
        // 指针数组
        vector<long> ptr(len, 1);
        vector<long> dp(n+1, 0);
        dp[1] = 1;
        for(int i=2;i<=n;++i){
            int flag = 0;
            dp[i] = primes[0] * dp[ptr[0]];
            for(int j=0; j<len; ++j){
                long cur = primes[j] * dp[ptr[j]];
                if(cur < dp[i]){
                    flag = j;
                    dp[i]= cur;
                }     
            }
            ptr[flag]++;
            // 如果当前值和上一个丑数一样,那么跳过该丑数
            if(dp[i] == dp[i-1]) i--;
        
        }
        return dp[n];
    }
};

你可能感兴趣的:(LeetCode刷题,leetcode,算法,职场和发展)