2021.08.09 Leetcode 313: 超级丑数 & 动态规划

题目套了一个素数的大主题,但其实和素数算法没什么关系,简而言之,就是提供一个数组arr,计算仅由arr数组中不同元素乘积出的数字,从小到大排序的第n个数字。

大致思路是dp数组中每个数字都可以由之前dp数组中的数字乘以prime数组中的各个数字得到,问题是,哪个dp数字乘以哪个prime数字可以得到下一个dp呢?无非是dp[0] * prime 与dp[1] * prime与dp[2]*prime中取第n个最小数。

那么我们可以用一个辅助数组point记录每个prime乘以第几个dp可能得到当前最小值,然后更新point数组,与最小值相等的point * prime的那个位置 + 1,这样每个prime数字乘的就是下一个最小的dp数字

以【2,7,11,13】为例
  1. dp[0] = min(2, 3, 5, 7) ->2
  2. dp[1] = min(2 * 2, 3, 5, 7) ->3
  3. dp[2] = min(2 * 2, 2 * 3, 5, 7) ->4
  4. dp[3] = min(3 * 2 , 2 * 3, 5, 7) ->5
  5. dp[4] = min(3 * 2, 2 * 3, 2 * 5, 7) -> 6
  6. dp[5] = min(4 * 2, 3 * 3, 2 * 5, 7) ->7

翻译

  1. dp[0] = min(dp[0] * 2, dp[0] * 3, dp[0] * 5, dp[0] * 7) ->2
  2. dp[1] = min(dp[1] * 2, dp[0] * 3, dp[0] * 5, dp[0] * 7) ->3
  3. dp[2] = min(dp[1] * 2, dp[1] * 3, dp[0] * 5, dp[0] * 7) ->4
  4. dp[3] = min(dp[2] * 2, dp[1] * 3, dp[0] * 5, dp[0] * 7) ->5
  5. dp[4] = min(dp[2] * 2, dp[1] * 3, dp[1] * 5, dp[0] * 7) -> 6
  6. dp[5] = min(dp[2] * 2, dp[1] * 3, dp[1] * 5, dp[1] * 7) ->7
注意!如第5步,2 * 3与3 * 2都是最小值,发生这种情况是因为dp数组记录了prime数组本身,就会发生交叉乘的情况,这时要一起改变相应的辅助数组值。
class Solution {
public:

    int nthSuperUglyNumber(int n, vector<int>& primes) {
        int primesSize = primes.size();
        vector<int> dp(n + 1, 1);
        vector<int> point(primesSize, 0);//每个质数对应的倍数(dp位置)
        for (int i = 1; i < n; i++){//dp从第二个开始计算
            int min_p = INT_MAX;
            for (int j = 0; j < primesSize; j++){
                min_p = min(min_p, dp[point[j]]  *primes[j]);
            }
            dp[i] = min_p;
            for(int j = 0; j < primesSize; j++)
            {
                if(dp[i] == dp[point[j]] * primes[j])//dp1=dp0*...
                {
                    point[j]++;
                }
            }
            cout << dp[i] << endl;
        }

        return dp[n - 1];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值