给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
示例:
输入: "aab"
输出: 1
解释: 进行一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
使用dfs完败,字符串中如果回文串少且长度够长,直接超时JJ。
1 public class _132 {
2
3 /**
4 * @param t 回文串的长度
5 * @param res 最少的分割次数
6 * @param depth 当前递归的层数
7 * @param cur 当前所在的字符位置
8 * @return 最小的分割次数
9 */
10 public int dfs(int[][] t , int res, int depth, int cur) {
11 if (res < depth || cur == -1) return res;
12
13 for (int i = t[cur][0]; i > 0; --i){
14 if (cur - t[cur][i] == -1) {
15 res = Math.min(res, depth);
16 }
17 res = Math.min(dfs(t, res, depth+1, cur-t[cur][i]), res);
18 }
19 return res;
20 }
21
22 public int minCut(String s) {
23 /// 查找s中最后一个字符的回文串,有几个不同的回文串就有几个分支
24 int len = s.length();
25 int[][] t = new int[len][2*len]; // t[i][...];t[i]是一个一维数组,它存储以i结尾的回文串的长度, 其中t[i][0]存储回文串的个数
26
27 for (int i = 0; i < len; i++){ // 判定奇数的回文串
28 for (int j = 0; i - j >= 0 && i + j < len; j++){ // j表示偏移长度
29 // 判定的字符串的边界: i-j, i+j
30 if (s.charAt(i-j) == s.charAt(i+j)){
31 int count = t[i+j][0];
32 t[i+j][count+1] = (i+j) - (i-j) + 1;
33
34 System.out.println("测试---"+(i-j)+", "+(i+j)+", "+(i+j-(i-j)+1));
35
36 ++t[i+j][0];
37 } else {
38 break;
39 }
40 }
41 }
42
43 for (int i = 0; i < len-1; i++){ // 判定偶数的回文串
44 for (int j = 0; i-j >= 0 && i+j+1 < len; j++){
45 // 边界为 i-j, i+1+j
46 if (s.charAt(i-j) == s.charAt(i+1+j)){
47 int count = t[i+1+j][0];
48 t[i+1+j][count+1] = (i+1+j+1) - (i-j);
49
50 System.out.println("测试---"+(i-j)+", "+(i+j+1)+", "+((i+1+j+1) - (i-j)));
51
52 ++t[i+1+j][0];
53 } else {
54 break;
55 }
56 }
57 }
58
59 // for (int i = 0; i < len; ++i){
60 // System.out.print("以"+i+"位置结束的回文串的长度:");
61 // for (int j = 1; j <= t[i][0]; ++j){
62 // System.out.print(t[i][j]+" ");
63 // }
64 // System.out.println();
65 // }
66 System.out.println("=================");
67 return dfs(t, 65535, 1, len-1)-1;
68 }
69
70 public static void main(String[] args) {
71 int res = new _132().minCut("alksjdfhgeiige");
72 System.out.println("answer: "+res);
73 }
74 }
来源:https://www.cnblogs.com/yfs123456/p/11510561.html