剑指49 丑数

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

 

示例:

输入: n = 10
输出: 12
解释: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 个丑数。
说明:  

1 是丑数。
n 不超过1690。

 

普通方法是从1往大遍历,每个数都判断一下是不是丑数,这样时间复杂度高。

用空间换时间,用一个数组记录已经产生的丑数,而且是按顺序排放的。

假设当前已产生的最大丑数为m,那么我们需要在m前面的丑数中找到这样三个数:*2大于m的最小数,*3大于m的最小数和*5大于m的最小数,这样可以从这三个数判断出下一个丑数是多少。

产生新的丑数后再相应地更新三个数的指针。

 1 class Solution {
 2 public:
 3     int nthUglyNumber(int n) {
 4         if(n<=0)
 5             return 0;
 6         int *uglynumbers=new int[n];
 7         uglynumbers[0]=1;
 8         int nextuglynum=1;
 9         int *mul2=uglynumbers,*mul3=uglynumbers,*mul5=uglynumbers;
10         while(nextuglynum<n){
11             uglynumbers[nextuglynum]=mymin(*mul2*2,*mul3*3,*mul5*5);
12             while(*mul2*2<=uglynumbers[nextuglynum])
13                 *mul2++;
14             while(*mul3*3<=uglynumbers[nextuglynum])
15                 *mul3++;
16             while(*mul5*5<=uglynumbers[nextuglynum])
17                 *mul5++;
18             nextuglynum++;
19         }
20 
21         int ugly=uglynumbers[nextuglynum-1];
22         delete []uglynumbers;
23         return ugly;
24     }
25 
26     int mymin(int a, int b, int c){
27         int ret=a<b?a:b;
28         return ret<c?ret:c;
29     }
30 };

 

posted @ 2020-07-05 20:16  __rookie  阅读(157)  评论(0编辑  收藏  举报