原题:
Write a program to find the n
-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5
. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12
is the sequence of the first 10
ugly numbers.
Note that 1
is typically treated as an ugly number, and n does not exceed 1690.
寻找并返回第n个ugly number。
ugly number的定义:因子只含有2,3,5的正整数(其中1是特殊的ugly number)。
(n不会超过1690)
思路:
主要思路是动态规划。
思路一:
建立一个大小为n的数组
min2 = min(nums[i] * 2), i ∈ (0, m - 1) (nums[i] * 2 > nums[m - 1])
min3 = min(nums[i] * 3), i ∈ (0, m - 1) (nums[i] * 3 > nums[m - 1])
min5 = min(nums[i] * 5), i ∈ (0, m - 1) (nums[i] * 5 > nums[m - 1])
所以第 m 个ugly number为min(min2, min3, min5)
但是重复计算的太多,勉强可以accepted。
class Solution {
public:
int nthUglyNumber(int n) {
vector<long int> uglyNums(n, INT_MAX);
uglyNums[0] = 1;
for(int i = 1; i < uglyNums.size(); i++) {
for(int j = 0; j < i; j++) {
uglyNums[i] = min(min(uglyNums[i],
(uglyNums[j]*2 > uglyNums[i - 1] ? uglyNums[j]*2 : INT_MAX)),
min((uglyNums[j]*3 > uglyNums[i - 1] ? uglyNums[j]*3 : INT_MAX),
(uglyNums[j]*5 > uglyNums[i - 1] ? uglyNums[j]*5 : INT_MAX)));
}
}
return uglyNums.back();
}
};
思路二:
每个ugly number(除了1,2,3,5),都是由一个比它小的ugly number乘以2或3或5得到的。
所以设3个pointer记录index。
nextUglyNum = min(uglyNums[pointer2] * 2, min(uglyNums[pointer3] * 3, uglyNums[pointer5] * 5));
然后将得到nextUglyNum的pointer++。
class Solution {
public:
int nthUglyNumber(int n) {
vector<long int> uglyNums(n, INT_MAX);
int pointer2 = 0, pointer3 = 0, pointer5 = 0;
uglyNums[0] = 1;
for(int i = 1; i < n; i++) {
long int nextUglyNum = min(uglyNums[pointer2] * 2, min(uglyNums[pointer3] * 3, uglyNums[pointer5] * 5));
if(nextUglyNum == uglyNums[pointer2] * 2) {
pointer2++;
}
if(nextUglyNum == uglyNums[pointer3] * 3) {
pointer3++;
}
if(nextUglyNum == uglyNums[pointer5] * 5) {
pointer5++;
}
uglyNums[i] = nextUglyNum;
}
return uglyNums.back();
}
};
(如果思路不好或者代码有能改进的地方请留言告诉我,谢谢。)