剑指offer-丑数

隐身守侯 提交于 2020-01-26 10:18:37

题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路
1.首先是怎么判断一个数是丑数?
如果能被2整除,那就让它连续除以2,直到不能再除了,
如果能被3整除,那就让它连续除以3,直到不能再除了
如果能被5整除,那就让它连续除以5,直到不能再除了
如果最后结果是1的话,那它就是一个丑数,否则就不是

public boolean isUgly(int num) {
        if(num < 1)
            return false;
        if(num == 1)
            return true;
        while(num % 2 == 0){
            num /= 2;
        }
        while(num % 3 == 0){
            num /= 3;
        }
        while(num % 5 == 0){
            num /= 5;
        }
        return num == 1? true:false;
    }

那么就进行遍历数字,直到找到第N个丑数

public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index < 1)
            return 0;
        int digit = 0;
        int i = 0;
        while(i < index){
            digit++;
            if(isUgly(digit)){  
                i++;
            }                                 
        }
        return digit;
    }
    public boolean isUgly(int num) {
        if(num < 1)
            return false;
        if(num == 1)
            return true;
        while(num % 2 == 0){
            num /= 2;
        }
        while(num % 3 == 0){
            num /= 3;
        }
        while(num % 5 == 0){
            num /= 5;
        }
        return num == 1? true:false;
    }
}

但是最后的结果是超时的,500 / 596 个通过测试用例,后面的数字是超时的
分析一下,效率较低的原因,对于每一个数都要去判断是否是丑数,不管之前是否已经判断过了,例如1400,判断1400的时候,1400/2 =700,那么要接着对700进行判断,700其实之前已经判断过是否为丑数了。无法对这些已知信息进行再利用,所以效率就很低。
因此,来看下一个方法

2.不去考虑非丑数,就是使用2,3,5来生成丑数,并且将丑数按序放在数组里面。

class Solution {
    public int nthUglyNumber(int n) {
       //用数组来存储所有的丑数,保持顺序就好
       //由于丑数都是*2 *3 *5得来的,所以维持三指针
       int[] dp = new int[n];
       dp[0] = 1;
       int i2 = 0,i3 = 0,i5 = 0;
       for(int i = 1;i < n;i++){
           int min = Math.min(dp[i2]*2,Math.min(dp[i3]*3,dp[i5]*5));
           if(min == dp[i2]*2) i2++;
           if(min == dp[i3]*3) i3++;//不能改成else if,因为使用if可以避免重复的情况,比如2*3和3*2
           if(min == dp[i5]*5) i5++;
           dp[i] = min;
       }
       return dp[n-1];
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!