一、題目名稱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個醜數的問題,網上已經有不少解題方法和大牛的博客能夠參考,這裏只是簡要說明我用的方法:
申請一個長度爲n的數組uglyNumbers,用於從小到大順序存儲n個醜數,數組中的首項爲1,即第一個醜數爲1
設置三個變量idx二、idx三、idx5存儲下標,初始值都爲0
找出數組uglyNumbers[idx2]*二、uglyNumbers[idx3]*三、uglyNumbers[idx5]*5的最小值,最小值即爲下一個醜數,同時更新最小值對應的下標,若是多個數字同時爲最小值,則它們的下標都要更新
找到第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