Leetcode 264(Ugly Number II)

Question

Write a program to find the nth ugly number.

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers.

Note that 1 is typically treated as an ugly number.

Hint

    1.The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
    2.An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
    3.The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.
    4.Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).

Analysis

找出第n个ugly数。

所谓ugly数,即质因子仅仅有2,3,5。即这个数仅通过2,3。5的相乘便能够得到。设1是ugly数。

依据给的线索,假设逐条推断该数是不是ugly,直到找到第n个ugly数。尽管方法行的通。可是因为大部分数都是非ugly的,这样做明显很耗时。

採用动态规划的思想。

每一个ugly数都是由2或3或5乘以另外一个ugly数组成。

设置三个指针。分别表示乘以2,3或5之前的ugly数。每次选择当前指针所指向位置的最小值,并将适当的某个指针前移一位。

指针设为index_2=0, index_3=0, index_5=0。值设为val_2=2, val_3=3, val_5=5。

设存储ugly的数组为arr。

1*2 2*2 3*2 4*2 5*2 6*2 8*2 9*2 10*2 12*2 15*2...
1*3 2*3 3*3 4*3 5*3 6*3 8*3 8*3 10*3 12*3 15*3... 
1*5 2*5 3*5 4*5 5*5 6*5 8*5 8*5 10*5 12*5 15*5...

迭代过程

  1. Iteration 1
    arr: 1
    arr[1]=(val_2 = 2) < (val_3 = 3) < (val_5 = 5)
    index_2=1, index_3=0, index_5=0;
    val_2=2*arr[index_2]=2*2=4;
    arr: 1, 2

  2. Iteration 2
    arr[2]=(val_3 = 3) < (val_2 = 4) < (val_5 = 5)
    index_2=1, index_3=1, index_5=0;
    val_3=3*arr[index_3]=6;
    arr:1, 2, 3

  3. Iteration 3
    arr[3]=(val_2 = 4) < (val_3 = 6) < (val_5 = 5)
    index_2=2, index_3=1, index_5=0;
    val_2=2*arr[index2]=6;
    arr:1, 2, 3, 4

  4. Iteration 4
    arr[4]=(val_5 = 5)<(val_2 = 6)=(val_3 = 6)
    index_2=2,index_3=1, index_5=1;
    val_5=5*arr[index_5]=10;
    arr:1, 2, 3, 4, 5

  5. Iteration 5
    arr[5]=(val_2=6)=(val_3=6)<(val_5=10)
    index_2=3, index_3=2, index_5=1;
    val_2=2*arr[index_2]=8;
    val_3=3*arr[index_3]=9;
    arr: 1, 2, 3, 4, 5, 6

Code

int minimal(int a, int b, int c){
        return (a<b?a:b)<c?(a<b?a:b):c;
}
int nthUglyNumber(int n) {
        int* arr=(int*)malloc(sizeof(int)*n);
        int index_2=0,index_3=0,index_5=0;
        int val_2=2, val_3=3, val_5=5;
        arr[0]=1;
        for(int i=1;i<n;i++){
                arr[i]=minimal(val_2,val_3,val_5);
                if(arr[i]==val_2)      val_2=arr[++index_2]*2;
                if(arr[i]==val_3)      val_3=arr[++index_3]*3;
                if(arr[i]==val_5)      val_5=arr[++index_5]*5;
        }
        return arr[n-1];
}
原文地址:https://www.cnblogs.com/zhchoutai/p/7103258.html