LeetCode:Ugly Number II - 醜數2:找出第n個醜數

一、題目名稱java

Ugly Number II(醜數2:找出第n個醜數)數組

二、題目地址函數

https://leetcode.com/problems/ugly-number-ii/.net

三、題目內容code

英文:Write a program to find the n-th ugly number.blog

中文:寫程序找出第n個醜數leetcode

說明:醜數具備以下特徵:1是醜數,醜數能夠表示爲有限個二、三、5的乘積開發

注意:關於「判斷指定數字是否爲醜數」,請參考Ugly Number(LeetCode #263)get

五、一個TLE的方法博客

一個最容易想到的方法,就是從1開始依次向後判斷各天然數是否爲醜數,一直判斷到第n個醜數,返回第n個醜數的值。這種方法因爲充斥了大量的重複計算,效率很低,所以會致使TLE(Time Limit Exceeded)的結果。

Java代碼以下:

/**
 * 功能說明:LeetCode 263 - Ugly Number
 * 開發人員:Tsybius2014
 * 開發時間:2015年8月23日
 */
public class Solution {
    
    /**
     * 求第N個醜數
     * @param n
     * @return 第N個醜數
     */
    public int nthUglyNumber(int n) {
    
        if (n <= 1) {
            return 1;
        }

        int counter = 0;
        for (int i = 1; ; i++) {
            
            if (isUgly(i)) {
                counter++;
                if (counter == n) {
                    return i;
                }
            } 
        }
    }
    
    /**
     * 判斷數字是否爲醜數
     * @param num 被判斷數字
     * @return true:醜數,false:非醜數
     */
    public boolean isUgly(int num) {
        
        if (num <= 0) {
            return false;
        }
        
        while (num % 2 == 0) num /= 2;
        while (num % 3 == 0) num /= 3;
        while (num % 5 == 0) num /= 5;
        
        if (num == 1) {
            return true;
        } else {
            return false;
        }
    }
}

六、解題方法

關於若是更加快速有效地找出第n個醜數的問題,網上已經有不少解題方法和大牛的博客能夠參考,這裏只是簡要說明我用的方法:

  1. 申請一個長度爲n的數組uglyNumbers,用於從小到大順序存儲n個醜數,數組中的首項爲1,即第一個醜數爲1

  2. 設置三個變量idx二、idx三、idx5存儲下標,初始值都爲0

  3. 找出數組uglyNumbers[idx2]*二、uglyNumbers[idx3]*三、uglyNumbers[idx5]*5的最小值,最小值即爲下一個醜數,同時更新最小值對應的下標,若是多個數字同時爲最小值,則它們的下標都要更新

  4. 找到第n個醜數時,循環結束

一段實現此方法的Java代碼以下:

/**
 * 功能說明:LeetCode 264 - Ugly Number II
 * 開發人員:Tsybius2014
 * 開發時間:2015年8月23日
 */
public class Solution {
    
    /**
     * 求第N個醜數
     * @param n
     * @return 第N個醜數
     */
    public int nthUglyNumber(int n) {
        
        int[] uglyNumbers = new int[n];
        uglyNumbers[0] = 1;
//      System.out.println("uglyNumbers[0]:1");
        
        int idx2 = 0;
        int idx3 = 0;
        int idx5 = 0;

        int counter = 1;
        while (counter < n) {

//          System.out.println("-----------");
//          System.out.println("idx2:" + idx2 + ";ugly[idx2]:" + uglyNumbers[idx2]);
//          System.out.println("idx3:" + idx3 + ";ugly[idx3]:" + uglyNumbers[idx3]);
//          System.out.println("idx5:" + idx5 + ";ugly[idx5]:" + uglyNumbers[idx5]);
//          System.out.println("idx2:" + idx2 + ";idx3:" + idx3 + ";idx5:" + idx5);
            
            int min = minOf(
                uglyNumbers[idx2] * 2, 
                uglyNumbers[idx3] * 3, 
                uglyNumbers[idx5] * 5);
            
            if (min == uglyNumbers[idx2] * 2) {
//              System.out.println("min==ugly[idx2]*2:" + uglyNumbers[idx2] * 2);
//              System.out.println("idx2:" + idx2 + "→" + (idx2 + 1));
                idx2++;
            }

            if (min == uglyNumbers[idx3] * 3) {
//              System.out.println("min==ugly[idx3]*3:" + uglyNumbers[idx3] * 3);
//              System.out.println("idx3:" + idx3 + "→" + (idx3 + 1));
                idx3++;
            }

            if (min == uglyNumbers[idx5] * 5) {
//              System.out.println("min==ugly[idx5]*5:" + uglyNumbers[idx5] * 5);
//              System.out.println("idx5:" + idx5 + "→" + (idx5 + 1));
                idx5++;
            }
            
            uglyNumbers[counter] = min;
//          System.out.println("uglyNumbers[" + counter + "]:" + min);
            counter++;
        }

//      System.out.println("-----------");
//      System.out.println("return:" + uglyNumbers[n - 1]);
        
        return uglyNumbers[n - 1];
    }
    
    /**
     * 求三個數字中最小的數字
     * @param a 數字a
     * @param b 數字b
     * @param c 數字c
     * @return a、b、c中最小的數字
     */
    private int minOf(int a, int b, int c) {
        int temp = a < b ? a : b;
        return temp < c ? temp : c; 
    }
}

爲了方便理解這段代碼,我在這段代碼里加入了System.out.println函數用於將結果輸出到控制檯。解除這些註釋行,並指定輸入的n爲15,執行函數時輸出到控制檯的結果以下:

uglyNumbers[0]:1
-----------
idx2:0;ugly[idx2]:1
idx3:0;ugly[idx3]:1
idx5:0;ugly[idx5]:1
idx2:0;idx3:0;idx5:0
min==ugly[idx2]*2:2
idx2:0→1
uglyNumbers[1]:2
-----------
idx2:1;ugly[idx2]:2
idx3:0;ugly[idx3]:1
idx5:0;ugly[idx5]:1
idx2:1;idx3:0;idx5:0
min==ugly[idx3]*3:3
idx3:0→1
uglyNumbers[2]:3
-----------
idx2:1;ugly[idx2]:2
idx3:1;ugly[idx3]:2
idx5:0;ugly[idx5]:1
idx2:1;idx3:1;idx5:0
min==ugly[idx2]*2:4
idx2:1→2
uglyNumbers[3]:4
-----------
idx2:2;ugly[idx2]:3
idx3:1;ugly[idx3]:2
idx5:0;ugly[idx5]:1
idx2:2;idx3:1;idx5:0
min==ugly[idx5]*5:5
idx5:0→1
uglyNumbers[4]:5
-----------
idx2:2;ugly[idx2]:3
idx3:1;ugly[idx3]:2
idx5:1;ugly[idx5]:2
idx2:2;idx3:1;idx5:1
min==ugly[idx2]*2:6
idx2:2→3
min==ugly[idx3]*3:6
idx3:1→2
uglyNumbers[5]:6
-----------
idx2:3;ugly[idx2]:4
idx3:2;ugly[idx3]:3
idx5:1;ugly[idx5]:2
idx2:3;idx3:2;idx5:1
min==ugly[idx2]*2:8
idx2:3→4
uglyNumbers[6]:8
-----------
idx2:4;ugly[idx2]:5
idx3:2;ugly[idx3]:3
idx5:1;ugly[idx5]:2
idx2:4;idx3:2;idx5:1
min==ugly[idx3]*3:9
idx3:2→3
uglyNumbers[7]:9
-----------
idx2:4;ugly[idx2]:5
idx3:3;ugly[idx3]:4
idx5:1;ugly[idx5]:2
idx2:4;idx3:3;idx5:1
min==ugly[idx2]*2:10
idx2:4→5
min==ugly[idx5]*5:10
idx5:1→2
uglyNumbers[8]:10
-----------
idx2:5;ugly[idx2]:6
idx3:3;ugly[idx3]:4
idx5:2;ugly[idx5]:3
idx2:5;idx3:3;idx5:2
min==ugly[idx2]*2:12
idx2:5→6
min==ugly[idx3]*3:12
idx3:3→4
uglyNumbers[9]:12
-----------
idx2:6;ugly[idx2]:8
idx3:4;ugly[idx3]:5
idx5:2;ugly[idx5]:3
idx2:6;idx3:4;idx5:2
min==ugly[idx3]*3:15
idx3:4→5
min==ugly[idx5]*5:15
idx5:2→3
uglyNumbers[10]:15
-----------
idx2:6;ugly[idx2]:8
idx3:5;ugly[idx3]:6
idx5:3;ugly[idx5]:4
idx2:6;idx3:5;idx5:3
min==ugly[idx2]*2:16
idx2:6→7
uglyNumbers[11]:16
-----------
idx2:7;ugly[idx2]:9
idx3:5;ugly[idx3]:6
idx5:3;ugly[idx5]:4
idx2:7;idx3:5;idx5:3
min==ugly[idx2]*2:18
idx2:7→8
min==ugly[idx3]*3:18
idx3:5→6
uglyNumbers[12]:18
-----------
idx2:8;ugly[idx2]:10
idx3:6;ugly[idx3]:8
idx5:3;ugly[idx5]:4
idx2:8;idx3:6;idx5:3
min==ugly[idx2]*2:20
idx2:8→9
min==ugly[idx5]*5:20
idx5:3→4
uglyNumbers[13]:20
-----------
idx2:9;ugly[idx2]:12
idx3:6;ugly[idx3]:8
idx5:4;ugly[idx5]:5
idx2:9;idx3:6;idx5:4
min==ugly[idx2]*2:24
idx2:9→10
min==ugly[idx3]*3:24
idx3:6→7
uglyNumbers[14]:24
-----------
return:24

END

相關文章
相關標籤/搜索