264. 丑数 II
————————————————————————————————————————————
编写一个程序,找出第 n 个丑数。
丑数就是只包含质因数 2, 3, 5 的正整数。
示例:
输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:
1 是丑数。
n 不超过1690。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ugly-number-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
————————————————————————————————————————————
解题思路:题目中可以知道,丑数就是只包含因数2,3,5的正整数,并且后面的丑数必然是前面的丑数通过*2,3,5来的,dp[i]用于存储第i位丑数的值。对于dp[i]之后的丑数,必定存在值为dp[i]*2、dp[i]*3、dp[i]*5的丑数。但同时有可能存在dp[i-1]*2、dp[i-1]*3、dp[i-1]5的值比前面的数的值大,因此需要将后面的丑数进行排序,我们需要做的就是将后面的丑数进行排序,我们用三个指针分别代表2,*3,*5的index。
例如已有[1],分别乘2,3,5,得到的丑数中最小的是2,则将2的指针+1。那么2的指针就是2。下一次迭代的时候,得到的值就是4,3,5,那么下一次迭代就是*3的指针+1。
但是注意存在一种情况,就是23=6,同时有32=6,这时候会存在重复的情况,所以我们在判断指针+1的时候,需要使用多个if,而不能使用if…else…,因为这样会导致出现重复的情况。
具体的C++代码如下:
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(n,1); //创建存储状态量的数组
int two = 0; //初始化*2的指针位置为0,以下指针类似,都初始化为0。
int three = 0;
int five = 0;
for(int i=1;i<n;i++)
{
dp[i] = min(dp[two]*2,min(dp[three]*3,dp[five]*5)); //分别将指针指向的丑数的值乘于2、3、4,并找到其中的最小值
if(dp[i]==dp[two]*2) //更新指针的索引位置
two++;
if(dp[i]==dp[three]*3)
three++;
if(dp[i]==dp[five]*5)
five++;
}
return dp[n-1];
}
};