把只包含因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含因子7。 習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。
因子中僅僅包含2、3、5的數,稱為醜數。比如說14,就不是醜數,因為因子包含7。
請輸出所有醜數中的第n個醜數。
第乙個是基本的思路。寫乙個函式判斷乙個數字n是不是醜數。
那麼可能會這麼寫:
static
boolean ugly(int n)
if (n % 3 == 0)
if (n % 5 == 0)
}return n == 1 ? true : false;
}
然後從1開始,計算沒乙個數字是不是醜數,是的話就計數加1。直到找到第n個醜數。
但是有什麼問題呢?效率不高。每乙個數字都要計算一遍是不是醜數。
能不能只計算醜數,而不考慮非醜數呢?
這個是個剪少我們的範圍的過程!有點類似於剪枝椏
這種思路的關鍵在於怎樣確保陣列裡面的醜數是排好序的。我們假設陣列中已經有若干個醜數,排好序後存在陣列中。我們把現有的最大醜數記做m。
現在我們來生成下乙個醜數,該醜數肯定是前面某乙個醜數乘以2、3或者5的結果。我們首先考慮把已有的每個醜數乘以2。在乘以2的時候,能得到若干個結果小於或等於m的。由於我們是按照順序生成的,小於或者等於m肯定已經在陣列中了,我們不需再次考慮;我們還會得到若干個大於m的結果,但我們只需要第乙個大於m的結果,因為我們希望醜數是按從小到大順序生成的,其他更大的結果我們以後再說。我們把得到的第乙個乘以2後大於m的結果,記為m2。同樣我們把已有的每乙個醜數乘以3和5,能得到第乙個大於m的結果m3和m5。
那麼下乙個醜數應該是m2、m3和m5三個數的最小者。
前面我們分析的時候,提到把已有的每個醜數分別都乘以2、3和5,事實上是不需要的,因為已有的醜數是按順序存在陣列中的。對乘以2而言,肯定存在某乙個醜數t2,排在它之前的每乙個醜數乘以2得到的結果都會小於已有最大的醜數,在它之後的每乙個醜數乘以2得到的結果都會太大。我們只需要記下這個醜數的位置,同時每次生成新的醜數的時候,去更新這個t2。對乘以3和5而言,存在著同樣的t3和t5。
package jianzhioffer;
public
class sloution31
// 求第n個醜數
public
static
intgetuglynumber_solution(int n)
data[0] = 1;
int pmul_2 = 0;
int pmul_3 = 0;
int pmul_5 = 0;
int index = 0;
while (index < n)
while (data[pmul_3] * 3 == data[index])
while (data[pmul_5] * 5 == data[index])
}return data[n];
}public
static
intmin(int a, int b, int c)
public
static
intmin(int a, int b)
}
2
3 4
5 6
8 9
10 12
15 16
18 20
24 25
27 30
32 36
40
碼農小汪 劍指Offer之15 樹的子結構
輸入兩顆二叉樹a,b,判斷b是不是a的子結構。題解 我們這個主要的問題就是,如何去判斷乙個是不是另乙個的子樹,首先一點。我們肯定涉及到對於樹的值得比較,肯定會和遍歷有關係啦。遍歷最簡單的遞迴去處理。package jianzhioffer 思路 1.我們要找到相同的根,然後進行一一的比較是否相等。這...
碼農小汪劍指Offer之37 平衡二叉樹判定
輸入一棵二叉樹,判斷該二叉樹是否是平衡二叉樹。求解二叉樹的高度,比較就知道了 package jianzhioffer public class sloution37 高度差正確就繼續求解,這裡寫的不好 求解高度沒有利用儲存起來 if math.abs getlength root.left get...
劍指offer之醜數
把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。對於這個問題,最容易想的就是乙個個數進行判斷,如 public static intgetuglynumber int ind...