Ugly Number II -- LeetCode
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.
思路:用dp。
我们用数组dp[]来记录ugly number的序列。dp[i]表示第i+1个ugly number。其中dp[0] = 1。由于所求的ugly number只可能含有2, 3, 5这三个质因子,因此我们在前面的ugly number上反复乘以这3个质因子就能得到后面的ugly number。
对于dp[1]来说,它应该等于min(dp[0] * 2, dp[0] * 3, dp[0] * 5) = dp[0] * 2 = 2。
之后,因为dp[0]*2这个ugly number已经被用过了,则dp[2]=min(dp[1] * 2, dp[0] * 3, dp[0] * 5).
因此,我们需要用3个指针记录这3个质因子的进度。需要注意的是,因为我们所需要的结果序列是不能有重复数字的,因此在min运算中,若3个乘积中有多个均为最小值时,应将这几个乘积对应的指针均加一。
算法复杂度O(n)
1 class Solution { 2 public: 3 int nthUglyNumber(int n) { 4 if (n <= 0) return -1; 5 vector<int> uglyNumber; 6 uglyNumber.push_back(1); 7 int pt2 = 0, pt3 = 0, pt5 = 0; 8 for (int i = 1; i < n; i++) { 9 int cur = std::min(uglyNumber[pt2] * 2, std::min(uglyNumber[pt3] * 3, uglyNumber[pt5] * 5)); 10 if (cur == uglyNumber[pt2] * 2) pt2++; 11 if (cur == uglyNumber[pt3] * 3) pt3++; 12 if (cur == uglyNumber[pt5] * 5) pt5++; 13 uglyNumber.push_back(cur); 14 } 15 return uglyNumber.back(); 16 } 17 };