剑指Offer 丑数 超详细讲解

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

解题思路:我第一个想法是先将前面几个丑数加进去然后从7开始遍历,每一个数都判断它是不是丑数,如果是就将它加进容器然后判断容器的大小是不是等于N。但是判断一个数是不是丑数非常的麻烦,注意题目的意思是只包含质因子2、3和5的数,它还可以包含其它的非质数因子,所以对一个数判断是不是丑数,首先要求出它的所有的因子,然后判断因子里面有没有不是2、3和5的质数,非常的麻烦,算法复杂度很高。我们可以转换一下思路,我们将丑数按照从小到大的顺序构造出来,就可以极大地降低复杂度。我们仔细查看前面几个丑数1 2 3 4 5 6 8 9 10 12 15,会发现2 = 1*2,3 = 1*3,4 = 2*2,5 = 1*5,6 = 2*3,8 = 2*4,9 = 3*3,10 = 2*5,12 = 2*6=3*4,15 = 3*5;我们会发现丑数都可以由在它前面的丑数通过乘以2,3,5来得到,这样既可以保证计算出来的数是丑数又简化了计算。以数字2为例我们可以发现它首先是第一个数乘以2得到2,然后第二个数乘以2得到4,然后第三个数乘以2得到6,然后第四个数乘以2得到8依次类推,对于3和5也是如此,此外我们还要注意到有可能某个数可能有多种方式得到比如12,所以我们可以用三个变量l2,l3,l5来记录2,3,5应该乘以的第几个数,用s2,s3,s5表示乘积然后选取最小的那个放入容器中,最后修改l2,l3,l5的值。AC代码如下:

import java.util.*;
public class Solution {
    public int GetUglyNumber_Solution(int index) {
        if(index == 0)
            return 0;
        ArrayList result = new ArrayList<>();
        result.add(1);
        int l2=0,l3=0,l5=0;
        int s2,s3,s5;
        int min;
        while(result.size()             s2 = result.get(l2)*2;
            s3 = result.get(l3)*3;
            s5 = result.get(l5)*5;
            min = Math.min(s2,Math.min(s3,s5));
            result.add(min);
            if(s2==min)
                l2++;
            if(s3==min)
                l3++;
            if(s5==min)
                l5++;
        }
        return result.get(index-1);
    }
    
}

你可能感兴趣的:(JAVA,学习,刷算法题)