碼農小汪 劍指Offer之31 醜數

2021-07-10 22:09:38 字數 1898 閱讀 7994

把只包含因子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...