剑指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 };