美文网首页
寻找第1500个丑数(JAVA代码)

寻找第1500个丑数(JAVA代码)

作者: kittaaron | 来源:发表于2020-02-18 18:23 被阅读0次

    这是一个常见的面试题目,关于什么是丑数,可以百度搜索。

    一种常见的思维是数字往前累加,判断是否是丑数,最后得出第N个丑数。

    另一思路是把已找到的数字作为基础数据,在已有的数据之后,找出一个比当前已找出的最大数要大的第1个丑数。

    下面是实现代码,可直接运行:

    package com.kittaaron.algorithm;
    
    import java.util.Arrays;
    
    /**
     * @author kittaaron
     *         created by 2/18/20
     */
    public class GetUglyNum {
        public static void main(String[] args) {
            int i = 1500;
            long firstStart = System.currentTimeMillis();
            findIthUglyByIncre(i);
            long firstEnd = System.currentTimeMillis();
            findIthUglyByCalc(i);
            long secondEnd = System.currentTimeMillis();
            System.out.println("算法1耗时:" + (firstEnd - firstStart) + "毫秒.");
            System.out.println("算法2耗时:" + (secondEnd - firstEnd) + "毫秒.");
        }
    
        private static void findIthUglyByIncre(long i) {
            long cnt = 0, start = 0;
            while(true) {
                start++;
                if (isUgly(start)) {
                    cnt++;
                }
                if (cnt == i) {
                    break;
                }
            }
            // 寻找第i个丑数
            System.out.println("第" + i + "个丑数是:" + start);
        }
    
        private static boolean isUgly(long num) {
            while (num % 2 == 0) {
                num /= 2;
            }
            while (num % 3 == 0) {
                num /= 3;
            }
            while (num % 5 == 0) {
                num /= 5;
            }
            return num == 1;
        }
    
        private static long findIthUglyByCalc(int i) {
            // ugArr为已经找出的丑数数组
            long firstUgly = 1;
            long[] arr = new long[i];
            arr[0] = firstUgly;
            int currentIdx = 0;
            while(currentIdx < i-1) {
                findNextUgly(arr, currentIdx);
                currentIdx++;
            }
            System.out.println("高效方法找到第" + i + "个丑数:" + arr[i-1]);
            //System.out.println("所有丑数:" + Arrays.toString(arr));
            return arr[i-1];
        }
    
        private static void findNextUgly(long[] arr, int currentMaxIdx) {
            long currentMax = arr[currentMaxIdx];
    
            // 从已找出来的数往前推,每个数字*2,如果比当前已找出的最大还大,继续往前推
            int tmp = currentMaxIdx;
            while (arr[tmp] * 2 > currentMax) {
                tmp--;
                if (tmp < 0) break;
            }
            long nextMulti2 = arr[tmp+1] * 2;
    
            // 从已找出来的数往前推,每个数字*3,如果比当前已找出的最大还大,继续往前推
            tmp = currentMaxIdx;
            while (arr[tmp] * 3 > currentMax) {
                tmp--;
                if (tmp < 0) break;
            }
            long nextMulti3 = arr[tmp+1] * 3;
    
            // 从已找出来的数往前推,每个数字*5,如果比当前已找出的最大还大,继续往前推
            tmp = currentMaxIdx;
            while (arr[tmp] * 5 > currentMax) {
                tmp--;
                if (tmp < 0) break;
            }
            long nextMulti5 = arr[tmp+1] * 5;
    
            long least = findLeast(nextMulti2, nextMulti3, nextMulti5);
            arr[currentMaxIdx+1] = least;
        }
    
        private static long findLeast(long i, long j, long k) {
            return i > j ? Math.min(j, k) : Math.min(i, k);
        }
    }
    

    本地运行结果如下:

    第1500个丑数是:859963392
    高效方法找到第1500个丑数:859963392
    算法1耗时:12079毫秒.
    算法2耗时:19毫秒.
    

    相关文章

      网友评论

          本文标题:寻找第1500个丑数(JAVA代码)

          本文链接:https://www.haomeiwen.com/subject/qgqnfhtx.html