前往
大廳
主題

LeetCode - 1201. Ugly Number III 解題心得

Not In My Back Yard | 2021-06-22 00:00:01 | 巴幣 0 | 人氣 234

題目連結:


題目意譯:
一個醜數為一正整數,其可以被 a 、 b 或是 c 所整除。

給定四整數 n 、 a 、 b 和 c ,回傳第 n 個醜數。

限制:
1 ≦ n 、 a 、 b 、 c ≦ 10 ^ 9
1 ≦ a × b × c ≦ 10 ^ 18
保證結果位於範圍 [1, 2 × 10 ^ 9] 中。



範例測資:
範例 1:
輸入: n = 3, a = 2, b = 3, c = 5
輸出: 4
解釋: 醜數們為 2, 3, 4, 5, 6, 8, 9, 10……第 3 個為 4。

範例 2:
輸入: n = 4, a = 2, b = 3, c = 4
輸出: 6
解釋: 醜數們為 2, 3, 4, 6, 8, 9, 10, 12……第 4 個為 6。

範例 3:
輸入: n = 5, a = 2, b = 11, c = 13
輸出: 10
解釋: 醜數們為 2, 4, 6, 8, 10, 11, 12, 13……第 5 個為 10。

範例 4:
輸入: n = 1000000000, a = 2, b = 217983653, c = 336916467
輸出: 1999999984


解題思維:
假設我們要求正整數 1 ~ K 之間有多少整數可以被 a 、 b 或是 c 整除(即求 1 ~ K 之間有多少醜數),則我們可以利用排容原理求得(Inclusion–Exclusion Principle,如這題所述),即
floor(K ÷ a) + floor(K ÷ b) + floor(K ÷ c)
- floor(K ÷ LCM(a, b)) - floor(K ÷ LCM(a, c)) - floor(K ÷ LCM(b, c))
+ floor(K ÷ LCM(a, b, c))
其中 floor() 為下高斯函數(對於正數來說,等價於無條件捨去小數部分)、LCM() 為求括號中的數字之最小公倍數(Lowest Common Divisor)。

有了以上算法之後,我們便可以將其套用在二分搜尋法(Binary Search)上用來判斷二分的「答案」(如這題):
令下界 L = 1 、上界 U = 2000000000。

接著每次二分時,令 M = (L + U) ÷ 2 ,如果 M 根據上面的算法得出的醜數數量 < n,則提高我們的下界 → 令 L = M + 1 ;反之,如果 M 得出的醜數數量 ≧ n,則降低上界 → U = M 。

當 L = U 時,此時的 L 即是第 n 個醜數。




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

花先生
看不懂
排容原理算出來的不是可被a,或b,或c整除的正整數有幾個嗎,為甚麼可以直接跟n去比較, n不是代表第n個醜數嗎
2022-01-19 10:58:23
Not In My Back Yard
首先,令 F(x) 為 1(含)~ x(含)有多少個醜數,而 F(x) 可利用排容原理算出(如文章內所述)。

那麼我們觀察 F(x) 的函數值:
假設 a = 3 、 b = 5 、 c = 17
那麼我們知道醜數們為 3 、 5 、 6 、 9 、 10 、……
因此當 x =
1 、 2 、 3 、 4 、 5 、 6 、 7 、 8 、 9 、 ……
時,我們會得到函數值為
0 、 0 、 1 、 1 、 2 、 3 、 3 、 3 、 4 、……

可以看到這個函數隨著輸入值 x 之值漸增,函數值也會非嚴格地漸增(也就是不會減少)。

因此當我們要找第 n 個醜數時,我們要找的是最小的 x 值使得 F(x) = n。

為何是最小的 x?從上面的例子,可以看到當我們要找第 3 個醜數時,我們有 x = 6 、 7 、 8 滿足 F(x) = 3,但是可以看到 6 才是我們要的,正是因為 6 是一個醜數,所以才會從 F(5) = 2 變為 F(6) = 3 的。
2022-01-19 19:37:09
Not In My Back Yard
那麼就是因為這個 F(x) 非遞減,所以我們可以利用二分搜尋法來找到這個最小的 x 值。

以同樣的例子,a = 3 、 b = 5 、 c = 17,然後我們要找到第 3 個醜數(n = 3):

假設我們基於某種原因知道了答案不會超過 x = 9,且必定至少 x = 1。

則我們求出 F((9 + 1) ÷ 2) = F(5) = 2。因為 2 < 3,也就是 1 ~ 5 只含有 2 個醜數,所以我們便可以知道答案至少 x = 5 + 1 = 6。

而這就是二分搜的精神。
2022-01-19 19:41:38
Not In My Back Yard
以上,希望有解答你的疑惑。
2022-01-19 19:41:52
花先生
另外求出來的醜數範圍了怎麼求得第n個,不解為甚麼L 就是答案 謝謝
2022-01-19 11:00:54

相關創作

更多創作