丑数问题 Ugly Number

2018-07-28 15:30:21

一、判断是否为丑数

问题描述:

问题求解:

所谓丑数,首先得是正数,然后其质数因子只包含了2,3,4,因此我们只需要对当前的数分别除2,3,4直到不能除为止。

    public boolean isUgly(int num) {
        if (num > 0) {
            for (int i = 2; i < 6; i++) {
                while (num % i == 0) num /= i;
            }
        }
        return num == 1;
    }

二、第n个丑数

问题描述:

问题求解:

由上面检测丑数的解法我们可以知道,每次丑数的生成都是使用2,3,5来乘已经生成的丑数,取其中最小的。为了降低不必要的比较,我们需要将当前2,3,5需要乘的丑数的下标保存下来,利用下标来进行快速的计算和判断。

    public int nthUglyNumber(int n) {
        int[] res = new int[n];
        int[] idx = new int[3];
        res[0] = 1;
        for (int i = 1; i < n; i++) {
            res[i] = Math.min(2 * res[idx[0]], Math.min(3 * res[idx[1]], 5 * res[idx[2]]));
            if (res[i] == 2 * res[idx[0]]) idx[0]++;
            if (res[i] == 3 * res[idx[1]]) idx[1]++;
            if (res[i] == 5 * res[idx[2]]) idx[2]++;
        }
        return res[n - 1];
    }

三、丑数问题的扩展

问题描述:

问题求解:

本题其实就是将丑数问题中质数从2,3,5扩展到了primes数组,本质的解法是一样的。

    public int nthSuperUglyNumber(int n, int[] primes) {
        int[] res = new int[n];
        int[] idx = new int[primes.length];
        res[0] = 1;
        for (int i = 1; i < n; i++) {
            res[i] = Integer.MAX_VALUE;
            for (int j = 0; j < primes.length; j++) {
                res[i] = Math.min(res[i], primes[j] * res[idx[j]]);
            }
            for (int j = 0; j < primes.length; j++) {
                if (primes[j] * res[idx[j]] <= res[i]) idx[j]++;
            }
        }
        return res[n - 1];
    }

这里可以对内层循环进行优化,将两次循环降低到一次循环,要做到这一步,就需要再申请大小为primes.length的数组,用来保存当前乘积。

    public int nthSuperUglyNumber2(int n, int[] primes) {
        int[] res = new int[n];
        int[] idx = new int[primes.length];
        int[] val = new int[primes.length];
        Arrays.fill(val, 1);
        int next = 1;
        for (int i = 0; i < n; i++) {
            res[i] = next;
            next = Integer.MAX_VALUE;
            for (int j = 0; j < primes.length; j++) {
                if (val[j] == res[i]) val[j] = primes[j] * res[idx[j]++];
                next = Math.min(next, val[j]);
            }
        }
        return res[n - 1];
    }
原文地址:https://www.cnblogs.com/hyserendipity/p/9382150.html