標籤:style blog color os strong 2014
題目來源,待字閨中,原創@陳利人 ,歡迎大家繼續關注公眾帳號“待字閨中”
3個字串a,b,c。判斷c是否是a和b的interleave,也就是c中應該有a,b中所有字 符,並且c中字元順序和a,b中一樣。比如,
1. a = "ef" b = "gh" c = "egfh" return true;2. a = "ef" b = "gh" c = "ehgf" return false。
這個題目中,並沒有說明a和b中是否有相同的字元,這個直接影響了最終的解法。所以,大家在面試的過程中,要和面試官進行互動,弄清楚之後再動手。我們這裡對於是否有相同的字元都給予分析。希望對大家有所協助。
a和b沒有相同字元的情況
這個情況處理起來比較簡單,逐個字元遍曆c字串,首先處理第一個字元,將其與a中的字元匹配,如果沒有匹配,則與b中的字元逐個匹配,如果沒有匹 配,則返回false;如果a中或者b中有一個字元和c的第一個字元匹配上了,則如上考慮第二個字元,與c的第一個字元匹配上的字串,也考慮第二個字 符,依次類推。直到c遍曆完,這時,如果a和b還有字元沒有遍曆,也返回false,都遍曆完畢,返回true。代碼如下:
bool interleave_diff(const char* a,const char* b,const char* c){int lenA = strlen(a),lenB = strlen(b),lenC = strlen(c);if(lenA + lenB != lenC)return false;int i = 0,j = 0,k = 0;while(c[k] != '\0'){if(a[i] == c[k]) i++;else if(b[j] == c[k]) j++;else return false;k++;}if(a[i] != '\0' || b[j] != '\0')return false;return true;}
a和b有相同字元的情況
上面的演算法,不能夠處理a和b中有相同字元的情況,例如a="XXY",b="XXZ",c="XXZXXY"。如果要處理,有相同字元的情況也是 比較直接的。有相同的出現,如果都匹配了c中的字元,則兩種匹配分別都考慮,只要有一個返回true,整個演算法就返回true。
所以,下面介紹一個動態規劃的解法。一個問題能夠用動態規劃來解的一個前提是:要有重複的子 問題。這樣把子問題的解儲存起來,後面重複利用才可以提高演算法的效率。這個問題有子問題嗎?考慮一個極端的例 子:a="XXX",b="XXX",c="XXXXXX"。子問題,顯然存在。再不然,畫出遞迴樹,就很明了了。
我們採用二維表來儲存子問題的結果,dp[i][j]如果為true,則表示c[0..i+j-1]是a[0..i-1]和b[0..j-1]的interleave字串。演算法實現的過程於上面的遞迴類似:
bool interleave_same(const char* a,const char* b,const char* c){int lenA = strlen(a),lenB = strlen(b),lenC = strlen(c);if(lenA + lenB != lenC)return false;bool dp[lenA+1][lenB+1];int i,j;for( i = 0;i <= lenA;i++){for(j = 0;j <= lenB;j++){if( i == 0 && j == 0)dp[i][j] = true;else if( i == 0) dp[i][j] = (b[j-1] == c[i+j-1]) && dp[i][j-1];else if( j == 0) dp[i][j] = (a[i-1] == c[i+j-1]) && dp[i-1][j];else dp[i][j] = ((a[i-1] == c[i+j-1]) && dp[i-1][j]) || ((b[j-1] == c[i+j-1]) && dp[i][j-1]);//狀態轉移方程式}}return dp[lenA][lenB];}
如有問題,請指正,謝謝