數對數目;及LIS問題分析

紫鳳發表於2013-11-01

今日面試題:數對數目

給定兩個陣列X和Y,元素都是正數。請找出滿足如下條件的數對的數目:

1. x^y > y^x,即x的y次方>y的x次方


2. x來自X陣列,y來自Y陣列

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

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

enter image description here

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

分析

這個題目與前幾期的題目頗有類似,而且,一個二叉樹的問題。通常來講,樹的問題一般都是可以通過遞迴來解決的。遞迴是自頂向下的分析問題,分析原問 題是否能夠分解為子問題。那麼LIS問題呢?我們從LIS集合大小入手,設f(x)為以x為根的數的LIS的大小,根據題目中的定義:

1. 當x不在LIS中時,f(x)=sum(所有兒子節點的f(兒子))

2. 當x在LIS中的時候,則x的兒子節點肯定不在LIS中,考慮孫子節點,則f(x)=sum(所有孫子節點的f(孫子)) + 1,後面的1是x本身。

上面的描述,轉換為程式碼,很簡單。但是效率確實很低,是指數級的。而且,上面的遞迴過程中,子問題重複的比較多。最明顯的就是,x的兒子 節點x的父節點的孫子節點,幾乎都要重複計算,所以改進空間很大。改進的方法,最直接的就是採用快取將計算過的子問題,快取起來,待後面直接使用,很簡 單,卻又是非常實用的。 那麼動態規劃如何解呢?動態規劃是自底向上解決問題,對於上面的遞迴過程,如何表示x是否在LIS中呢?微博上@曹鵬博士 給出的解法是非常好的:

1. dp[0,1][x]表示以節點x為根的子樹不取或取x的結果,第一維取0,表示x不在LIS中,第一維取1,表示x在LIS中;

2. dp[0][leaf]=0,dp[1][leaf]=value of the leaf

3. dp[0][x]=max of max dp[t=0,1][y is son of x], dp[1][x]=sum of dp[0][y is son of x] + value of x.

4. 最後取max(dp[0][root],dp[1][root])

這裡比較有意思的是第一維來表示第二維的節點,作為根節點,是否在LIS中。上面的過程在,前序或者後序的基礎之上進行都可以,原則就是一點,有兒子的,就先計算完兒子,再計算父節點。

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

相關文章