剑指offer--丑数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40921797/article/details/81979995

把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:一般人往往都会想到一种很暴力的方法,从最小的丑数开始逐一递增,判断每个数是不是丑数,从而求处第n个丑数。可是这个方法虽然很容易实现,可以试过就知道。因为时间复杂度,和空间复杂度限制,通过率 0.00%
那么我们换位思想,我们拿到一个数求他是不是丑数,行不通,那么就只能根据小的丑数,求大的丑数了。
我们规定了只包含质因子2,3,5的是丑数,也就是说,一个数可以有有限个2 和有限个3 和有限个5相乘的来,换言之,这个数可以最后分解成n1个2,n2个3,n3个5组成,我们还知道 1 是最小的丑数。那么如何从1推出下一个丑数呢。我们在列举几个丑数观察。
1, 2, 3, 4, 5, 6, 8, 9, .。。。
1 , 1*2, 1*3, 2*2, 1*5, 2*3/3*2,4*2, 3*3。。。
我们发现每个数,都可以有前面某个数 ×2 或者 ×3 或者 ×5得到。如果排个顺序,那就是第i个数后面的数就是前面某几个数*2,*3,*5中的较小值。因为*2,*3,*5的增长速度不同,所以需要3 个标记分别记录寻找是那个数乘。如果这个数*2<第i个数,那么肯定不会*2得到第i+1个数,这时候就需要标记位置+1了。
代码实现:

class Solution {
public:
    int GetMin(int a,int b,int c)
    {
        if(a < b)
            return a < c ? a : c;
        else 
            return b < c ? b : c;
    }
    int GetUglyNumber_Solution(int index) {
        if(index < 0)
            return -1;
        int pos2 = 1,pos3 = 1,pos5 = 1;
        int* arr = new int[index + 1];
        arr[1] = 1;
        for(int i=2;i <= index;i++)
        {
            arr[i] = GetMin(arr[pos2]*2,arr[pos3]*3,arr[pos5]*5);
            if(arr[pos2]*2 <= arr[i])
                pos2++;
            if(arr[pos3]*3 <= arr[i])
                pos3++;
            if(arr[pos5]*5 <= arr[i])
                pos5++;
        }
        return arr[index];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_40921797/article/details/81979995