1. 程式人生 > >LeetCode-131.分割回文串(相關話題:動態規劃、深度優先)

LeetCode-131.分割回文串(相關話題:動態規劃、深度優先)

給定一個字串 s,將 s 分割成一些子串,使每個子串都是迴文串。

返回 s 所有可能的分割方案。

示例:

輸入: "aab"

輸出:

[
  ["aa","b"],
  ["a","a","b"]
]

思路:

  1. 動態規劃判s[i~j]是否為迴文串
  2. 深度優先搜尋所有可能的分割方案

Java程式碼:

public List<List<String>> partition(String s) {
    List<List<String>> result = new LinkedList<>();
    int len = s.length();
    if (0 < len) {
        // 1.動態規劃判s[i~j]是否為迴文串
        boolean[][] f = new boolean[len][len];
        for (int i = 0; i < len; i++)
            f[i][i] = true;
        for (int i = len-1; i >= 0; i--) {
            for (int j = i; j < len; j++) {
                if (j == i) {
                    f[i][j] = true;
                    continue;
                }

                if (j - 1 == i) {
                    f[i][j] = s.charAt(i) == s.charAt(j);
                    continue;
                }

                f[i][j] = f[i+1][j-1] && s.charAt(i) == s.charAt(j);
            }
        }

        // 2.深度優先搜尋所有可能的分割方案
        List<String> tmp = new ArrayList<>();
        dfs(0, s, f, tmp, result);
    }

    return result;
}
private void dfs(int i, String s, boolean[][] f, List<String> tmp, List<List<String>> result) {
    if (i == s.length()) {
        result.add(new ArrayList<>(tmp));
        return;
    }

    for (int k = i; k < s.length(); k++) {
        if (!f[i][k])
            continue;

        tmp.add(s.substring(i, k+1));
        dfs(k+1, s, f, tmp, result);
        tmp.remove(tmp.size()-1);
    }
}