分割回文串【JAVA實現】

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

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

示例:

輸入: "aab"
輸出:
[
  ["aa","b"],
  ["a","a","b"]
]

面對這種需要列出所有可能性的問題,很容易想到的就是使用回溯的方法來解決,分析問題,首先需要把一個複雜的問題分解成相對來說較爲簡單的子問題,然後將這個子問題的解進行組合就可以找到複雜問題的解了。

舉例:

aabb
先考慮在第 1 個位置切割,a | abb
這樣我們只需要知道 abb 的所有結果,然後在所有結果的頭部把 a 加入
abb 的所有結果就是 [a b b] [a bb]
每個結果頭部加入 a,就是 [a a b b] [a a bb]

aabb
再考慮在第 2 個位置切割,aa | bb
這樣我們只需要知道 bb 的所有結果,然後在所有結果的頭部把 aa 加入
bb 的所有結果就是 [b b] [bb]
每個結果頭部加入 aa,就是 [aa b b] [aa bb]

aabb
再考慮在第 3 個位置切割,aab|b
因爲 aab 不是迴文串,所有直接跳過

aabb
再考慮在第 4 個位置切割,aabb |
因爲 aabb 不是迴文串,所有直接跳過

最後所有的結果就是所有的加起來
[a a b b] [a a bb] [aa b b] [aa bb]

對這個思路進行編碼

class Solution {
    String s;
    List<List<String>> res = new ArrayList<>();
    public List<List<String>> partition(String s) {
        this.s = s;
        List<String> list = new ArrayList<>();
        dfs(list,0);
        return res;
    }
    public void dfs(List<String> list,int index) {
        //已經到了字符串的結尾了,把結果集放到最終解中
        if (index == s.length()) {
            res.add(new ArrayList<>(list));
            return;
        }
        //不斷取更長的頭串
        for (int i = index;i < s.length();i++) {
            if (isPartition(index,i)) {//判斷頭串是否是迴文
                String temp = s.substring(index,i+1);
                list.add(temp);
                //對後面的字符串進行遞歸,進行相同的處理
                dfs(list,i+1);
                //刪除結尾已有結果,回到上一層(回溯的精髓)
                list.remove(list.size()-1);
            }
        }
    }
    //判斷字符串的某一段是否是迴文
    public boolean isPartition(int start,int end) {
        while (start < end) {
            if (s.charAt(start) != s.charAt(end)) {
                return false;
            }
            start++;
            end--;
        }
        return true;
    }
}

其實這樣是比較直接的解決問題了,這個解法中還有可以優化的地方,就是判斷是否是迴文的地方,我們會有很多重複的判斷。比如已經判斷過“aa”是迴文了,但是判斷“baab”是否是迴文的時候還會重複判斷,這個地方是可以優化的,我們可以用一個二維空間記錄判斷過迴文的字符串,這樣就不用重複的進行判斷了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章