标签:
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.
Hint:
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.Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
Subscribe to see which companies asked this question
解法1:从2到n循环,对每个数进行isUgly判断,会超时Time Limit Exceeded
class Solution { public: int nthUglyNumber(int n) { int num = 2; while(n > 1) { if(isUgly(num)) --n; ++num; } return --num; } private: bool isUgly(int num) { while(num > 0 && num % 2 == 0) num /= 2; while(num > 0 && num % 3 == 0) num /= 3; while(num > 0 && num % 5 == 0) num /= 5; return num == 1; } };
解法2:根据提供的Hint,我们知道丑陋数序列可以拆分为下面3个子列表:
(2) 1×2, 2×2, 3×2, 4×2, 5×2, …
(3) 1×3, 2×3, 3×3, 4×3, 5×3, …
(5) 1×5, 2×5, 3×5, 4×5, 5×5, …
一个新的丑数可以看做是一个旧的丑数乘以2,3,5得到的(第一个丑数是1,第二个为2,则第二个可以看做第一个丑数*2得到了第二个丑数(1*2、1*3和1*5中的最小者)),本题解题难点在于维护丑数数列为从小到大排列的顺序。
根据上述思路可以做如下实现:
class Solution { public: int nthUglyNumber(int n) { int count = 1; int num = 1; list<int> l2; list<int> l3; list<int> l5; while(count != n) { l2.push_back(2*num); l3.push_back(3*num); l5.push_back(5*num); int l2min = l2.front(); int l3min = l3.front(); int l5min = l5.front(); int minNum = min(l2min, min(l3min, l5min)); if(l2min == minNum) l2.pop_front(); if(l3min == minNum) l3.pop_front(); if(l5min == minNum) l5.pop_front(); num = minNum; ++count; } return num; } };
改进:对于乘以2而言,肯定存在某一个丑数t2,使得排在它之前的每一个丑数乘以2得到的结果都会小于已有最大丑数,在它之后的每个丑数乘以2得到的结果都会大于当前最大丑数。我们只需要记下这个丑数的位置,同时每次生成新的丑数时去更新这个t2。对于3和5,同样存在t3和t5。
class Solution { public: int nthUglyNumber(int n) { vector<int> uglyNumSeq(1, 1); int i2 = 0, i3 = 0, i5 = 0; while (uglyNumSeq.size() < n) { int n2 = uglyNumSeq[i2] * 2; int n3 = uglyNumSeq[i3] * 3; int n5 = uglyNumSeq[i5] * 5; int next = min(n2, min(n3, n5)); if (next == n2) ++i2; if (next == n3) ++i3; //注意不用else if,因为不同序列可能有相同值 if (next == n5) ++i5; uglyNumSeq.push_back(next); } return uglyNumSeq.back(); } };
[LeetCode]70. Ugly Number II第N个丑数
标签:
原文地址:http://www.cnblogs.com/aprilcheny/p/4950442.html