思路:
每一个丑数都是前面某一个丑数乘以2,3,5得到的结果的最小值得到的
比如第一个丑数数1, 1 * 2, 1*3, 1*5,之中的最小值是2,所以第二个丑数就是2 丑数序列为1 2
同样,这个丑数序列每一个乘以2 ,3 ,5
得到2 4 (乘以2的时候)
3 6 (乘以3的时候)
5 10 (乘以5的时候)
取大于2的最小值是3.。。。。。其他依次类推
---------------------
但是,这样,每次前面的丑数都要乘2 3 5 ,然后再取他们大于 已知序列最大丑数 的最小值, 复杂度是很高的。
不必要每次都要前面的所有的丑数都去相乘2 3 5 。
对于乘以2来说,肯定在已知的丑数序列中存在某一个丑数,排在它前面的丑数乘以2得到的结果都是小于等于以知序列的最大丑数,排在他后面的丑数乘以2得到的结果都是大于已知序列的最大丑数,我们只需记这个丑数的位置,,每次更新这个位置即可
乘3 和乘5的也是这样。
class Solution {
public:
int GetUglyNumber_Solution(int index)
{
if(index <= 0)
return 0;
int * res = new int[index +1];
res[0] = 1;
int start = 1;
int p1 = 0;//res[p1]*2第一个乘以2大于已知序列最大丑数的数字
int p2 = 0;//res[p2]*3第一个乘以3大于已知序列最大丑数的数字
int p3 = 0;//res[p3]*5第一个乘以5大于已知序列最大丑数的数字
while(start <= index - 1)
{
int ugly = Min(res[p1]*2, res[p2] * 3, res[p3] * 5);
//cout<<ugly<<endl;
res[start] = ugly;//记录得到的丑数
while(res[p1] *2 <= res[start])//更新丑数序列中第一个乘2大于已知最大丑数的位置
++p1;
while(res[p2] *3 <= res[start])//同上
++p2;
while(res[p3] * 5 <= res[start])//同上
++p3;
start++;
}
int result = res[index - 1];
delete []res;
return result;
}
int Min(int x, int y, int z)
{
int temp = x < y ? x : y;
return z < temp ? z : temp;
}
};