1. 程式人生 > >Leetcode 264(Ugly Number II)

Leetcode 264(Ugly Number II)

type 明顯 word vertical only == app hidden 指向

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];
}

Leetcode 264(Ugly Number II)