劍指offer
contents我們把只包含質因子 2、3 和 5 的數稱作醜數(ugly number)。求按從小到大的順序的第 n 個醜數。思考:為什麼不會漏掉醜數,或者出現重複的醜數?
示例:
輸入: n = 10
輸出: 12
解釋: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 是前 10 個醜數。
說明:根據醜數的定義,我們可以判斷任何乙個數字是否是醜數。所以可以從1開始,判斷每個正整數是否是醜數(不斷取餘,做除法),配合乙個計數變數,就可以得到第n個醜數。
這種做法需要大量的取餘和除法運算。
class
solution
return num;
}private
boolean
isugly
(int num)
}
超時。但是這裡的isugly()
方法值得借鑑,很明確的看出了如何判斷醜數。
根據醜數的定義,每個醜數的只包含因子2,3,5,也就是說,醜數應該是另乙個醜數乘以2、3、5的結果。通過這種方式,我們可以通過已有的醜數,找到新的醜數。
這種思路的關鍵在於如何保證得到的醜數序列是有序的?解決上述問題,採用三指標法:
三個指標初始化指向第乙個醜數1,然後分別計算三個指標指向的數字乘2/3/5的結果,將其中最小的結果加入醜數序列,後移對應的指標。
class
solution
return uglynums[n - 1];
}}
複雜度分析
時間複雜度o(n)
空間複雜度o(n)
一種粗暴的思路是直接對於當前已有的醜數陣列裡邊的每個數字乘以2,3,5,然後去重,排序。
上述的三指標的思路看起來優雅很多,但是為什麼不會漏掉,或者多計算出一些重複的醜數呢?
為什麼不會漏掉?
對於a,b,c三個指標,每次只取乘積結果最小的那個結果,然後把對應指標後移一位。那麼不是最小的指標是不會動的,所以實際上粗暴解法裡的每乙個數字,三指標法裡邊都計算到了。所以不可能漏掉。
為什麼每次得到的最小結果一定是比已有最大醜數更大的醜數?
以下是執行過程中的乙個狀態,可以看到a最後指向5,上一次a'指向4,上次生成的最大醜數是末尾的8。
由於陣列是完全有序的,而且每個指標對應乘以的倍數是不變的,所以uglynums[a]*2
必然大於uglynums[a']*2
。
而uglynums[b]*3
和uglynums[c]*5
沒有被選到,說明這兩個也必然大於uglynums[a']*2
。
1
2<--c(乘5的指標)
3<--b(乘3的指標)
4<--a'(乘2的指標)
5<--a(乘2的指標)
68
為什麼不會出現重複?
前面已經證明了,每一輪迴圈得到的醜數一定比已有最大醜數更大,這裡是嚴格大於關係,不可能出現相等。
那麼出現重複只可能在一輪迴圈內部,也就是min函式比較的三者有兩個是重複的,那麼結果是這兩個指標都會後移一次,所以結果當中不會生成2個重複的數字。
劍指Offer 49 醜數
我們把只包含因子2 3和5的數稱為醜數。求按從小到大的順序的第1500個醜數。例 6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當作第乙個醜數。遍歷數字,對每個數字判斷是否只包含2 3 5因子。問題在於,有很多無用的計算,增加時間複雜度。時間複雜度 o n 空間複雜度 o 1 可以發現...
劍指offer49 醜數
把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。思路 1.每次找出乙個最小丑數res i 都會產生三個新的醜數,2 res i 3 res i 5 res i 2.如果我...
劍指 Offer 49 醜數
我們把只包含質因子 2 3 和 5 的數稱作醜數 ugly number 求按從小到大的順序的第 n 個醜數。出看這道題可能感覺能算,但是思路就非常繁瑣。解法一 這個只說說思路,既然2,3,5是該數的因子,那麼該數除以2,3,5的餘數一定是 0 那麼就讓每個數連續除以2,3,5,只到餘數不為0 結果...