【剑指Offer-时间效率与空间效率的平衡】面试题49:丑数

题目描述

把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

思路1

对每个数字都判断该数字是不是丑数,然后返回第N个丑数即可。丑数的判断方法是:如果一个数字能被2整除,就连续除以2直到不能被2整除为止,如果此时该数字能被3整除,则连续除以3,直到不能被3整除为止,如果此时该数字能被5整除,则连续除以5,直到该数字不能被5整除为止,如果此时该数字为1,则原数字为丑数,否则不是丑数。代码如下:

class Solution {
public:
    bool isUglyNumber(int number){  //判断number是否为丑数
        while(number%2==0)
            number /= 2;
        while(number%3==0)
            number /= 3;
        while(number%5==0)
            number /= 5;
        
        if(number==1)
            return true;
        else return false;
    }
    
    int GetUglyNumber_Solution(int index) {
        if(index==1)
            return 1;
        
        int i=1;
        int j=2;
        while(i<index){
            if(isUglyNumber(j))
                i++;
            j++;
        }
        return j;
    }
};

由于该算法对每个数字都要判断是否为丑数,时间复杂度过高,在牛客网上无法通过。

思路2

如果一个数是丑数,那么这个数乘以2、乘以3或者乘以5得到的结果也是丑数。因此,我们可以创建一个数组,里面是排序好的丑数,每一个丑数都是前面的丑数乘以2、3或5得到的。这种思路的难点在于如何保持该数组是排好序的。假设该数字目前的最大值是M,则M肯定是前面的某个丑数乘以2、3或5得到的。将前面的丑数乘以2时能得到若干小于等于M的结果,因为数组是排序的,这个结果已经存在于数组当中了,还会得到若干大于M的结果,我们将这个结果的最小值记为M2,同时记录计算出该结果的下标index2,下一次在计算时,不用从头开始计算了,只需从index2计算就行了。同样的,我们可以得到M3,M5,index3,index5。因为数组是排序的,所以下一个丑数是M2,M3,M5的最小值。代码如下:

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        int* uglyNums = new int[index];
        uglyNums[0] = 1;
        
        int* multiply2 = uglyNums;
        int* multiply3 = uglyNums;
        int* multiply5 = uglyNums;
        
        int nextUglyIdx = 1;
        while(nextUglyIdx<index){
            int minUglyNum = getMin(*multiply2*2, *multiply3*3, *multiply5*5);
            uglyNums[nextUglyIdx] = minUglyNum;
            while(*multiply2*2<=minUglyNum)
                multiply2++;
            while(*multiply3*3<=minUglyNum)
                multiply3++;
            while(*multiply5*5<=minUglyNum)
                multiply5++;
            nextUglyIdx++;
        }
        
        int ans = uglyNums[index-1];
        delete[] uglyNums;
        return ans;
    }
    
    int getMin(int num1, int num2, int num3){
        int minNum = (num1<num2)? num1:num2;
        minNum = (minNum<num3)? minNum:num3;
        return minNum;
    }
};

猜你喜欢

转载自www.cnblogs.com/flix/p/12516135.html
今日推荐