You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.0 KiB
208 lines
5.0 KiB
package class11;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
// 本题测试链接 : https://leetcode.com/problems/palindrome-partitioning-ii/
|
|
public class Code02_PalindromePartitioningII {
|
|
|
|
// 测试链接只测了本题的第一问,直接提交可以通过
|
|
public static int minCut(String s) {
|
|
if (s == null || s.length() < 2) {
|
|
return 0;
|
|
}
|
|
char[] str = s.toCharArray();
|
|
int N = str.length;
|
|
boolean[][] checkMap = createCheckMap(str, N);
|
|
int[] dp = new int[N + 1];
|
|
dp[N] = 0;
|
|
for (int i = N - 1; i >= 0; i--) {
|
|
if (checkMap[i][N - 1]) {
|
|
dp[i] = 1;
|
|
} else {
|
|
int next = Integer.MAX_VALUE;
|
|
for (int j = i; j < N; j++) {
|
|
if (checkMap[i][j]) {
|
|
next = Math.min(next, dp[j + 1]);
|
|
}
|
|
}
|
|
dp[i] = 1 + next;
|
|
}
|
|
}
|
|
return dp[0] - 1;
|
|
}
|
|
|
|
public static boolean[][] createCheckMap(char[] str, int N) {
|
|
boolean[][] ans = new boolean[N][N];
|
|
for (int i = 0; i < N - 1; i++) {
|
|
ans[i][i] = true;
|
|
ans[i][i + 1] = str[i] == str[i + 1];
|
|
}
|
|
ans[N - 1][N - 1] = true;
|
|
for (int i = N - 3; i >= 0; i--) {
|
|
for (int j = i + 2; j < N; j++) {
|
|
ans[i][j] = str[i] == str[j] && ans[i + 1][j - 1];
|
|
}
|
|
}
|
|
return ans;
|
|
}
|
|
|
|
// 本题第二问,返回其中一种结果
|
|
public static List<String> minCutOneWay(String s) {
|
|
List<String> ans = new ArrayList<>();
|
|
if (s == null || s.length() < 2) {
|
|
ans.add(s);
|
|
} else {
|
|
char[] str = s.toCharArray();
|
|
int N = str.length;
|
|
boolean[][] checkMap = createCheckMap(str, N);
|
|
int[] dp = new int[N + 1];
|
|
dp[N] = 0;
|
|
for (int i = N - 1; i >= 0; i--) {
|
|
if (checkMap[i][N - 1]) {
|
|
dp[i] = 1;
|
|
} else {
|
|
int next = Integer.MAX_VALUE;
|
|
for (int j = i; j < N; j++) {
|
|
if (checkMap[i][j]) {
|
|
next = Math.min(next, dp[j + 1]);
|
|
}
|
|
}
|
|
dp[i] = 1 + next;
|
|
}
|
|
}
|
|
// dp[i] (0....5) 回文! dp[0] == dp[6] + 1
|
|
// (0....5) 6
|
|
for (int i = 0, j = 1; j <= N; j++) {
|
|
if (checkMap[i][j - 1] && dp[i] == dp[j] + 1) {
|
|
ans.add(s.substring(i, j));
|
|
i = j;
|
|
}
|
|
}
|
|
}
|
|
return ans;
|
|
}
|
|
|
|
// 本题第三问,返回所有结果
|
|
public static List<List<String>> minCutAllWays(String s) {
|
|
List<List<String>> ans = new ArrayList<>();
|
|
if (s == null || s.length() < 2) {
|
|
List<String> cur = new ArrayList<>();
|
|
cur.add(s);
|
|
ans.add(cur);
|
|
} else {
|
|
char[] str = s.toCharArray();
|
|
int N = str.length;
|
|
boolean[][] checkMap = createCheckMap(str, N);
|
|
int[] dp = new int[N + 1];
|
|
dp[N] = 0;
|
|
for (int i = N - 1; i >= 0; i--) {
|
|
if (checkMap[i][N - 1]) {
|
|
dp[i] = 1;
|
|
} else {
|
|
int next = Integer.MAX_VALUE;
|
|
for (int j = i; j < N; j++) {
|
|
if (checkMap[i][j]) {
|
|
next = Math.min(next, dp[j + 1]);
|
|
}
|
|
}
|
|
dp[i] = 1 + next;
|
|
}
|
|
}
|
|
process(s, 0, 1, checkMap, dp, new ArrayList<>(), ans);
|
|
}
|
|
return ans;
|
|
}
|
|
|
|
// s[0....i-1] 存到path里去了
|
|
// s[i..j-1]考察的分出来的第一份
|
|
public static void process(String s, int i, int j, boolean[][] checkMap, int[] dp,
|
|
List<String> path,
|
|
List<List<String>> ans) {
|
|
if (j == s.length()) { // s[i...N-1]
|
|
if (checkMap[i][j - 1] && dp[i] == dp[j] + 1) {
|
|
path.add(s.substring(i, j));
|
|
ans.add(copyStringList(path));
|
|
path.remove(path.size() - 1);
|
|
}
|
|
} else {// s[i...j-1]
|
|
if (checkMap[i][j - 1] && dp[i] == dp[j] + 1) {
|
|
path.add(s.substring(i, j));
|
|
process(s, j, j + 1, checkMap, dp, path, ans);
|
|
path.remove(path.size() - 1);
|
|
}
|
|
process(s, i, j + 1, checkMap, dp, path, ans);
|
|
}
|
|
}
|
|
|
|
public static List<String> copyStringList(List<String> list) {
|
|
List<String> ans = new ArrayList<>();
|
|
for (String str : list) {
|
|
ans.add(str);
|
|
}
|
|
return ans;
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
String s = null;
|
|
List<String> ans2 = null;
|
|
List<List<String>> ans3 = null;
|
|
|
|
System.out.println("本题第二问,返回其中一种结果测试开始");
|
|
s = "abacbc";
|
|
ans2 = minCutOneWay(s);
|
|
for (String str : ans2) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
|
|
s = "aabccbac";
|
|
ans2 = minCutOneWay(s);
|
|
for (String str : ans2) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
|
|
s = "aabaa";
|
|
ans2 = minCutOneWay(s);
|
|
for (String str : ans2) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
System.out.println("本题第二问,返回其中一种结果测试结束");
|
|
System.out.println();
|
|
System.out.println("本题第三问,返回所有可能结果测试开始");
|
|
s = "cbbbcbc";
|
|
ans3 = minCutAllWays(s);
|
|
for (List<String> way : ans3) {
|
|
for (String str : way) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
}
|
|
System.out.println();
|
|
|
|
s = "aaaaaa";
|
|
ans3 = minCutAllWays(s);
|
|
for (List<String> way : ans3) {
|
|
for (String str : way) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
}
|
|
System.out.println();
|
|
|
|
s = "fcfffcffcc";
|
|
ans3 = minCutAllWays(s);
|
|
for (List<String> way : ans3) {
|
|
for (String str : way) {
|
|
System.out.print(str + " ");
|
|
}
|
|
System.out.println();
|
|
}
|
|
System.out.println();
|
|
System.out.println("本题第三问,返回所有可能结果测试结束");
|
|
}
|
|
|
|
}
|