33. Ugly numbers

Topic description

         Call numbers that contain only factors 2, 3, and 5 Ugly Numbers;

         For example, 6 and 8 are ugly numbers, but 14 is not because it contains the factor 7;

         Traditionally we treat 1 as the first ugly number. Find the Nth ugly number in ascending order;

Problem solving ideas

         Let's talk about a violent solution first to provide ideas;

         If p is an ugly number, then p=2^x * 3^y * 5^z, then you can get different ugly numbers by assigning different values ​​to x, y, and z;

         If you want to find the ugly numbers sequentially, you need to know the following characteristics: For any ugly number p: 2*p, 3*p, 5*p are all ugly numbers, and 2*p<3*p<5*p; If p<q, then 2*p<2*q, 3*p<3*q, 5*p<5*q;

          Since 1 is the smallest ugly number, starting from 1, compare 2*1, 3*1, 5*1, and the smallest one is the next ugly number of 1, which is 2*1;

          At this time, there is one more ugly number '2', and there are three more ugly numbers that can be compared, 2*2, 3*2, 5*2,

          At this time, add the ugly number generated by '1' and the ugly number generated by '2', that is, (3*1, 5*1, 2*2, 3*2, 5*2) for comparison, and find out the smallest;

          If this cycle continues, you will find that each time an ugly number is selected, the ugly number will generate 3 new ugly numbers for comparison;

          Next, say an O(n) algorithm;

          Since there is p<q, then 2*p<2*q, then "I" is not selected in front of the number smaller than you, and the new ugly number you generate later must be larger than "I", then you multiply by 2

The generated ugly number must be bigger than the one I multiply by 2, then you will have the chance to choose it after I choose it.

         In fact, we only compare 3 numbers each time: the smallest number for multiplying by 2, the smallest number for multiplying by 3, and the smallest number for multiplying by 5. That is to compare (2*x, 3*y, 5*z), x>=y>=z,

         Focus on the role of p in the following code: int p[] = new int[] { 0, 0, 0 }; p[0] represents the minimum [position] in the array a for multiplying the comparison number by 2.

    final int d[] = {2, 3, 5};

    private int finMin(int num2, int num3, int num5) {
        int min = Math.min(num2, Math.min(num3, num5));
        return min == num2? 0: min == num3? 1: 2;
    }

    public int GetUglyNumber_Solution(int index) {

        if (index == 0){
            return 0;
        }

        int a[] = new int[index];

        a[0] = 1; //1 is the first ugly number

        int p[] = new int[]{0, 0, 0};
        int num[] = new int[]{2, 3, 5};
        int cur = 1;

        while (cur < index) {

            int m = finMin(num[0], num[1], num[2]);

            if (a[cur - 1] < num[m])
                a[cur++] = num[m];

            p[m] += 1;

            num[m] = a[p[m]] * d[m];
        }

        return a[index - 1];
    }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325868427&siteId=291194637