LIS問題;及最少插入字元分析

紫鳳發表於2013-11-01

今日面試題:LIS問題

這個LIS問題,可不是Longest Increasing Subsequence,而是Largest Independent Set,含義如下:給定一棵二叉樹,找到滿足如下條件的最大節點集合:集合中的任意兩個節點之間,都沒有邊。如下圖:

enter image description here

LIS大小為5,為{10,40,60,70,80}.

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

最少插入字元分析原題給定字串,可以通過插入字元,使其變為迴文。求最少插入字元的數量。例如:

1. ab最少插入1個字元,變為*b*ab

2. aa最少插入0個字元

3. abcd最少插入3個字元,*dcb*abcd

分析

這個題目的分析思路,和前面兩期是非常相似的:給出遞迴的解法,發現重複的子問題,改進為動態規劃的解法,這是一個分析的過程,待同學們比較熟悉時候,可以直接給出動態規劃的解決方案,就很好了。

這個題目,遞迴該如何解呢?給定一個字串str,長度為n,怎麼插入最少的字元,是的字串變為迴文呢?插入最少的字元,就是要儘量利用原來的字元,在原字串str中,儘量利用更多能夠匹配的字元。怎麼對這個問題進行分解呢?考慮str字串整體:

1. 如果str[0]==str[n-1],則問題轉變為求str[1,n-2],插入最少字元,得到迴文

2. 如果str[0]!=str[n-1],則需要插入一個字元要麼和str[0]相同,要麼和str[n-1]相同,

    1. 如果和str[0],則轉變為str[1,n-1],插入最少字元,得到迴文

    2. 如果和str[n-1],則轉變為str[0,n-2],插入最少字元,得到迴文

上面的第2種情況中,需要取兩個值最小值。則完成了問題的分解,並且,基本情況也分析完全,則有遞迴式為:fmi(str, l, h) = (str[l] == str[h]) ? fmi(str, l+1, h-1) : (min(fmi(str, i+1, h), fmi(str,l, h-1))+1) 通過上面的式子,有經驗的、熟練的同學,很直接的就能看出來,存在重複的子問題,這就意味著,我們可以講子問題的解快取使用。如果,沒有直接能夠看出來的同學們,還是可以按照我們之前的方法,把遞迴樹畫出來吧,那樣更加一目瞭然。

那麼,這個題目該如何用動態規劃的解決呢?如何重複利用子問題的解呢?似乎有些不那麼直接。但其實也是於規律可循的。上面的遞迴式,是從字串的兩 邊,想中間移動遞迴,根據動態規劃解決問題的思想,我們先解決子問題,再重複利用子問題,就是要從內向外解決,大家還記得迴文子串判斷的那個題目麼,動態 規劃解法的外層迴圈是子串的長度,這個題目也是類似的。示例程式碼如下:

enter image description here

這個題目在使用動態規劃解的時候,略有點兒繞,不太好想到如何利用子問題的解。這個沒有更好的方法,就是多多積累,遇到問題勤于思考,舉一反三。

【分析完畢】

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

相關文章