丑数 二 ---- 设计一个算法,找出只含素因子`2`,`3`,`5` 的第 n 小的数

Posted smren

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了丑数 二 ---- 设计一个算法,找出只含素因子`2`,`3`,`5` 的第 n 小的数相关的知识,希望对你有一定的参考价值。

题目 -丑数 二

设计一个算法,找出只含素因子235 的第 n 小的数。

符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...

我们可以认为1也是一个丑数

分析

根据题目可得,丑数即由若干个2、3、5相乘所的到的数。可以写成

2^a + 3^b + 5^c

a,b,c可以取随意自然数

再进一步分析,可以得到每个丑数都存在另一个丑数乘以2、3、5中的一个数,与之相等。

题目要求要第n个小的丑数。

第一种思路

第一种思路,第n小的丑数,那就把丑数都列出来从小到大排序即可,进而推演,即找出最小的丑数,然后将之乘以2、3、5,然后将结果与之前的所有丑数进行对比,再找出最小的丑数,进行一个循环,最后将第n次选出的最小的丑数返回。

这种思路每次都要遍历一遍数组,效率过慢。

第二种思路

把所有除了1的丑数分为三组,第一组是最小的丑数乘以2的,第二组是最小的丑数乘以3的,第三组是最小的丑数乘以5的。这样的话没组的数字都是有序的,我们只需将每组中的最小的进行比较,然后将最小的踢出自己的数组,然后用最小的数分别乘以2、3、5,将乘出的数分别放回三个数组。

例:

2: 2,4,6,10....

3: 3,6,9,15....

5: 5,10,15,20....

代码实现如下:

 public int nthUglyNumber(int n) {
        // write your code here
        
        List<Integer> l2 = new ArrayList<>();
        List<Integer> l3 = new ArrayList<>();
        List<Integer> l5 = new ArrayList<>();
        
        int min = 1;
        int f1 = 0;
        int f2 = 0;
        int f3 = 0;
        
        for(int i = 1; i<n; i++){
            l2.add(min*2);
            l3.add(min*3);
            l5.add(min*5);
            
            min = Math.min(Math.min(l2.get(f1),l3.get(f2)),l5.get(f3));
            if(min == l2.get(f1)){
                f1++;
            }
            if(min == l3.get(f2)){
                f2++;
            }
            if(min == l5.get(f3)){
                f3++;
            }
            
        }
        return min;
    }

或者是下面这种代码实现方式:

将数都放在一个数组中,用f1,f2,f3来控制2,3,5组的推进。

public int nthUglyNumber(int n) {
        // write your code here
        
        List <Integer> ints = new ArrayList<>();
        int f1 = 0;
        int f2 = 0;
        int f3 = 0;
        
        
        ints.add(1);
        for(int i = 1; i<n; i++){
            int n1 = 2 * ints.get(f1);
            int n2 = 3 * ints.get(f2);
            int n3 = 5 * ints.get(f3);
            int min =  Math.min(Math.min(n1,n2),n3);
            if(min == n1){
                f1++;
            }
            if (min == n2){
                f2++;
            }
            if(min == n3){
                f3++;
            }
            
            ints.add(min);
            
        }
        return ints.get(n-1);
    }

以上是关于丑数 二 ---- 设计一个算法,找出只含素因子`2`,`3`,`5` 的第 n 小的数的主要内容,如果未能解决你的问题,请参考以下文章

4. 丑数 II

c语言:把只含因子23和5的数称为丑数,求按从小到大的顺序的第1500个丑数(两种方法比较)

经典算法详解寻找丑数

算法分析---寻找丑数

剑指offer——49

⭐算法入门⭐《二分枚举》中等05 —— LeetCode 1201. 丑数 III