题目描述
把只包含因子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;
}
};