Write a program to find the n
-th ugly number.html
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5
. git
Example:github
Input: n = 10 Output: 12 Explanation: is the sequence of the first ugly numbers.1, 2, 3, 4, 5, 6, 8, 9, 10, 1210
Note: app
1
is typically treated as an ugly number.n
does not exceed 1690.Hint:post
isUgly
for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
这道题是以前那道 Ugly Number 的拓展,这里让找到第n个丑陋数,还好题目中给了不少提示,基本上至关于告诉咱们解法了,根据提示中的信息,丑陋数序列能够拆分为下面3个子列表:url
仔细观察上述三个列表,能够发现每一个子列表都是一个丑陋数分别乘以 2,3,5,而要求的丑陋数就是从已经生成的序列中取出来的,每次都从三个列表中取出当前最小的那个加入序列,请参见代码以下:spa
解法一:code
class Solution { public: int nthUglyNumber(int n) { vector<int> res(1, 1); int i2 = 0, i3 = 0, i5 = 0; while (res.size() < n) { int m2 = res[i2] * 2, m3 = res[i3] * 3, m5 = res[i5] * 5; int mn = min(m2, min(m3, m5)); if (mn == m2) ++i2; if (mn == m3) ++i3; if (mn == m5) ++i5; res.push_back(mn); } return res.back(); } };
咱们也能够使用最小堆来作,首先放进去一个1,而后从1遍历到n,每次取出堆顶元素,为了确保没有重复数字,进行一次 while 循环,将此时和堆顶元素相同的都取出来,而后分别将这个取出的数字乘以 2,3,5,并分别加入最小堆。这样最终 for 循环退出后,堆顶元素就是所求的第n个丑陋数,参见代码以下:htm
解法二:blog
class Solution { public: int nthUglyNumber(int n) { priority_queue<long, vector<long>, greater<long>> pq; pq.push(1); for (long i = 1; i < n; ++i) { long t = pq.top(); pq.pop(); while (!pq.empty() && pq.top() == t) { t = pq.top(); pq.pop(); } pq.push(t * 2); pq.push(t * 3); pq.push(t * 5); } return pq.top(); } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/264
相似题目:
参考资料:
https://leetcode.com/problems/ugly-number-ii/
https://leetcode.com/problems/ugly-number-ii/discuss/69372/Java-solution-using-PriorityQueue