1. 程式人生 > >小米oj 6 交叉佇列

小米oj 6 交叉佇列

引用塊內容描述
給出三個佇列 s1,s2,s3 ,判斷 s3 是否是由 s1 和 s2 交叉得來。 如:s1 為 aabcc , s2 為 dbbca。 當 s3 為 aadbbcbcac 時,返回 true(即將 s1 拆成三部分: aa,bc,c 分別插入 s2 對應位置) 否則返回 false。

輸入 aabcc,dbbca,aadbbcbcac

輸出 true

解釋:

大概思想如下:
1. 動態規劃求解,構造一個長為 len2=s2.size()+1,寬為 len1=s1.size()+1 的 dp[][] 二維陣列;
2. 設有 i,j,其中 i表示字串 s1 的第 i 個字元, j 表示字串 s2 的第 j 個字元, t=i+j 表示 s3 的第 t 個字元;
3. dp[i][j] 如果為 1 ,表示 s1[i] 等於 s3[t] 且 dp[i−1][j] 等於 1 、 或者 s2[j] 等於 s3[t] 且 dp[i][j−1] ;
4. 簡單的說 dp[i][j] 為 1 就表示這個點可達,以 dp[0][0] 為起點, dp[len1][len2] 為終點,dp陣列中值為 1 的點為路徑,向下走表示取 s1 的字元,向右走表示取 s2
的字元。這樣就將抽象的字元組合轉化成了更好理解的二維陣列來表示;
5. 最優子結構即為: s1,s2 的 i,j 點字元之前的字元能否交叉組合成字串 s3 的前 i+j 個字元,轉換到二維陣列即為, i,j 點左側點和上方的點是否可達。

博主本身對此也嘗試著讀懂,可是還是沒有掌握動態規劃的思路,待博主好好研究一番在與大家交流,先貼上程式碼

private static String solution(String line) {
    // 在此處理單行資料
    String[] arr1 = line.split(",");
    int len1 = arr1[0].length();
    int len2 = arr1[1].length();
    int len3 = arr1[2].length();

    if (len3 != len1 + len2)
        return false
+ ""; if (len1 == 0) return (arr1[1] == arr1[2]) + ""; if (len2 == 0) return (arr1[0] == arr1[2]) + ""; int[][] dp = new int[len1 + 1][len2 + 1]; dp[0][0] = 1; // init the dp array for (int i = 1; i <= len1; i++) { if (arr1[0].charAt(i-1) == arr1[2].charAt(i-1
)) dp[i][0] = dp[i - 1][0]; } for (int i = 1; i <= len2; i++) { if (arr1[1].charAt(i-1) == arr1[2].charAt(i-1)) dp[0][i] = dp[0][i - 1]; } // dp for (int i = 1; i < len1 + 1; i++) { for (int j = 1; j < len2 + 1; j++) { int t = i + j; if (arr1[0].charAt(i-1) == arr1[2].charAt(t-1)) { dp[i][j] = dp[i - 1][j] | dp[i][ j]; } if (arr1[1].charAt(j-1) == arr1[2].charAt(t-1)) { dp[i][j] = dp[i][j - 1] | dp[i][j]; } } } // 返回處理後的結果 if (dp[len1][len2] == 1) return true + ""; return false + ""; }