leetcode刷题,总结,记录,备忘 313

leetcode313Super Ugly Number

Write a program to find the nth super ugly number.

Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32]is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.

Note:
(1) 1 is a super ugly number for any given primes.
(2) The given numbers in primes are in ascending order.
(3) 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.

这道题也是借鉴了别人的博客,并自己非常仔细的理解透彻,琢磨清楚了。使用动态规划的方法,用一个数组来存储n个超级丑数。我们可以知道,第一个超级丑数一定是1,所以result[0] = 1,之后的n-1个数都是在1的基础上与primes这个数组中的每个质数相乘得来。所以以result中已得到的超级丑数的个数与n的关系来确定外层循环。内层循环遍历primes数组,将每个质数与result数组中相应的数相乘,取最小的,放入result中,知道result中的数量到达n为止。其中有个细节,就是在一轮循环中,找出某个最小数的时候,必须将他的索引值记下来,来标primes中该位的数已经和result中的第一个数相乘过了,所以下次,就该与result中的第二个数相乘。用一个index数组来保存primes的相应索引的质应该与result中的哪个数进行相乘。比如说一开始result中只有一个1,primes中每个数都和1相乘,2最小,放入result中,相应的是primes中的第1索引的值2得出的结果,所以相应的index数组中的index[0]必须++,在下一轮循环中的时候,primes中的2就是和result中的第二个元素2相乘了,避免重复相乘,具体看代码内容。最后部分,判断结果是否与之前的result中的元素相同即可,相同的排除掉。

class Solution {
public:
    int nthSuperUglyNumber(int n, vector<int>& primes) {
        vector<int> result(n);
        vector<int> index(primes.size(), 0);
        
        result[0] = 1;
        int count = 1;
        
        while (count < n)
        {
            int min = INT_MAX;
            int minindex;
            for (int i = 0; i < primes.size(); ++i)
            {
                int temp = result[index[i]] * primes[i];
                if (temp < min)
                {
                    min = temp;
                    minindex = i;
                }
            }
            
            index[minindex]++;
            if (min != result[count-1])
            {
                result[count] = min;
                count++;
            }
        }
        
        return result[n-1];
        
    }
};


你可能感兴趣的:(leetcode刷题,总结,记录,备忘 313)