问题描述: 给定一个字符串s,将s分割成一些子串,使每个子串都是回文串。 返回s所有可能的回文串分割方案。

样例

给出

s = “aab”

返回

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

思路:

注意到在判断回文串的过程中,有大量的重复计算,一个回文串的判定是根据其子串是否是回文串来判断的 举个例子,有字符串

“abcba”

其子串

”bcb“

也是一个回文串 自然想到动态规划

解法

维护一个二维数组,两个下标分别代表起始位置,这样一个数组元素就惟一的表示了一个字串是否是回文串,如果对应的字符串是回文串,那么置为1,否则为 -1,初始化为 0 再利用DFS搜索,由于从数组获取了信息,因此搜索过程中发生了剪枝 source code language:java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

public class solution {
    private List<List<String>> cases;
    private int[][] map;
    private String insideStr;
    private Stack<String> list;

    public List<List<String>> partition(String s){
        if(s==null||s.length() == 0){
            return null;
        }
        map = new int[s.length()][s.length()];
        for(int i = 0; i < s.length() ;++i){
            for(int j = 0; j<s.length();++j){
                map[i][j] = 0;
            }
        }
        insideStr = s;
        cases = new ArrayList<>();
        list = new Stack<>();
        findCase(0);
        return cases;
    }

    public void findCase(int start){
        if(start>=insideStr.length()){
            cases.add((Stack<String>)list.clone());
            return;
        }
        for(int i = start;i<insideStr.length();++i){
            int j = 0;
            boolean breakflag = false;
            while(start+j<=i-j) {
                if (map[start+j][i-j] == 1){
                    map[start][i] = 1;
                    break;
                }
                if(map[start+j][i-j] == -1){
                    map[start][i] = -1;
                    breakflag = true;
                    break;
                }
                if(insideStr.charAt(start+j)!=insideStr.charAt(i-j)){
                    map[start+j][i-j] = -1;
                    map[start][i] = -1;
                    breakflag = true;
                    break;
                }
                j++;
            }
            if(!breakflag){
                map[start][i] = 1;
                list.add(insideStr.substring(start, i+1));
                findCase(i + 1);
                list.pop();
            }
        }
    }
}