分詞問題;及最大乘積分析

紫鳳發表於2013-11-01

今日面試題:分詞問題

給定字串,以及一個字典,判斷字串是否能夠拆分為欄位中的單詞。例如,欄位為{hello,world},字串為hellohelloworld,則可以拆分為hello,hello,world,都是字典中的單詞。

==================================================

最大乘積分析

原題

一根繩子,長度為n米。將其切成幾段,每一段的長度都是整數。請給出一種切法,使得切成的各段繩子之間的乘積是最大的。注意,最少要切一下的。

分析

這個題目如何一步一步的分析呢?不管切幾段,總有第一段,第二段…等等。第一段的長度有哪些選擇呢?可以是1、2、3...一直到n-1(至少要切一下),我們用max_prod(n)表示長度為n的繩子的切法中,乘積最大的值。那麼:

1. 當第一段長度為1時,最大的乘積為:max(1×max_prod(n-1), 1×(n-1))

2. 當第一段長度為2時,最大的乘積為:max(2×max_prod(n-2), 2×(n-2))

3. …

4. 當第一段長度為n-1時,最大的乘積為:(n-1)*1=n-1

上面為什麼是取max呢?注意,題目中的要求,至少是要切一下的。這樣,從上面的分析中得出,遞迴的表示式,設第一段繩子的長度為i,取 值範圍為[1,n-1],則,對於每一個i,有最大乘積為:max(i×(n-i),i×max_prod(n-i))。然後對所有的i,求的最大值,就 是最終的答案。

這個題目到這裡完了麼?看過我們以前分析的同學,很快就能想到,進而檢視,這些子問題中是否有重複的,如果有,則可以採用動態規劃的方法進行演算法改 進。而檢視是否有重複遞迴子問題,一個比較好的方法,就是在紙上畫出遞迴樹,然後是否有重複的遞迴子問題。就一目瞭然了。這個題目是比較明顯的,同學們可 以嘗試自己在紙上畫畫,練習一下。

既然,我們已經明確了重複的遞迴子問題,然後呢?相信專門學習過動態規劃專題的同學,都會記得這樣的一句話:“自頂向下的分析問題,自底向上的解決 問題”,大概類似,可能並不是原話。自底向上解決問題的意思就是先解決小問題,然後依據這些小問題的結果,再解決一批問題,依次直至解決整個問題:

1. 當繩子的長度為1的時候,忽略,不能切

2. 當繩子的長度為2的時候,切一刀,max_prod[2]=1×1

3. 當繩子的長度為3的時候,切一刀,max_prod[3]=1×2

4. 當繩子的長度為4的時候,依賴前面每一個長度的切法,並且,第一個長度從2開始。

5. …

這個,狀態轉移方程可以表示為:max_prod[i]=max((i-j)×j, j×max_prod[i-j]),其中j的範圍是[1,i/2]。顯然,動態規劃方法的時間複雜度為O(n^2),空間複雜度為O(n)。

這個問題,到這裡,已經挺不錯的。不過,還沒完,這個題目是有更加巧妙的方法的。在微博上,有的同學給出瞭如下的方法:只需要將長度n表示為 3x+2y=n,並且3儘可能的多,這樣的3^x+2^y是最大的。不得不讚嘆,這確實是一個很巧妙的方法。大家可以通過例子,驗證幾個。為什麼只有3和 2呢?長度為4的,就是2×2,5以上的,都可以分解為3x+2y,並且3^x+2^y>5以上的數字。這個題目要求是整數,如果取消這個限制呢? 擴充思路,舉一反三,請大家多多思考。

【分析完畢】

本文來自微信:待字閨中,2013-10-14釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。

相關文章