• 【剑指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;
        }
    };
    
  • 相关阅读:
    爱福窝在线装修设计软件测评
    关于简书首页模式的思考和畅想
    这些O2O比你们更靠谱儿
    iOS动画——Layer Animations
    最大流, 最小割问题及算法实现
    浅谈iOS学习之路
    iOS架构师之路:慎用继承
    iOS架构师之路:控制器(View Controller)瘦身设计
    IOS中的编码规范
    关闭键盘导致tableView:didSelectRowAtIndexPath:失效解决办法
  • 原文地址:https://www.cnblogs.com/flix/p/12516135.html
Copyright © 2020-2023  润新知