这个题之前在热题做过了,不过题就是要多做嘛。
此题我们可以先用数学的方法尝试一下排序:
1,2,3,5,4,6,10
上述排序是比较直观的,类似于队列的形式。每次排出一部所有,然后都乘2,3,5. 但是从上述例子就可以看出是不对的,因为4应该在5前面。
由于丑数是累乘得到的,我们可以用3个指针分别存2,3,5指向的位置,因为每个数都要乘所有之前的丑数。每次通过循环取最小的即可。
去重:由于可能有重复丑数出现,我们每次要判断三个指针有没有指向重复的元素,有的话,就都向前移动指针。比map去重高效很多。
typedef pair<int, int> P;
class Solution {
public:
int nthUglyNumber(int n) {
vector<int> dp(3), uglys{1}, primes{2,3,5};
for(int i=0;i<n;i++)
{
int mi = min({uglys[dp[0]]*2, uglys[dp[1]]*3, uglys[dp[2]]*5});
uglys.push_back(mi);
for(int i=0;i<3;i++)
if(uglys[dp[i]]*primes[i] == mi)
dp[i]++;
}
return uglys[n-1];
}
};