题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:
用一个数组存储所有已经找到的丑数,始终有一个指针指向最大的丑数,3个指针分别指向 左侧三个数,作用是找到比当前最大数大的最小的数
这三个数分别是m2,m3,m5 意思是第一个数的二倍,第二数的3倍,第三个数的5倍,分别比当前最大数大,从这三个乘完的数中挑一个最小的作为最新的最大值。
自己写的版本1: 缺点是 不够彻底的初始化 用1就够了 不用 1~5
class Solution { public: void CompareMinOfTree(int *&mtwo,int *&mtree,int *&mfive,int *&max){ int m2 = *mtwo*2; int m3 = *mtree*3; int m5 = *mfive*5; int result; result=m2>m3?m3:m2; result=result>m5?m5:result; *(max+1) = result; max++; if(result==m2) mtwo++; if(result==m3) mtree++; if(result==m5) mfive++; } int GetUglyNumber_Solution(int index) { if(index<=0) return 0; int answer[]={1,2,3,4,5}; if(index<6) return answer[index-1]; int *ulist = new int[index]; memcpy(ulist,answer,sizeof(answer)); int *big2=ulist+2,*big3=ulist+1,*big5=ulist+1,*Max=ulist+4; for(int i=5;i<index;i++){ CompareMaxOfTree(big2,big3,big5,Max); } return *Max; } };
版本2:用1初始化 三个指针初始化至数组首地址 每次先获得当前2/3/5后的最小值 并放入数组 重置当前最大值
然后比较三个指针膨胀2/3/5和当前最大值的大小 保证前者膨胀后恰好比后者大
class Solution { public: int CompareMinOfTree(int a, int b, int c){ int result=a>b?b:a; result = result>c?c:result; return result; } int GetUglyNumber_Solution(int index) { if(index<=0) return 0; int *ulist = new int[index]; //初始化 *ulist = 1; int curMax = *ulist; int *mtw=ulist,*mtr=ulist,*mf=ulist; for(int i=1;i<index;i++){ ulist[i]=CompareMinOfTree(*mtw*2,*mtr*3,*mf*5); curMax = ulist[i]; if(*mtw*2 <= curMax) mtw++; if(*mtr*3 <= curMax) mtr++; if(*mf*5 <= curMax) mf++; } return curMax; } };