题目连接
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Stack;
public class Solution {
//动态规划 记录能构成回文的分割 存储上一次分割点下标
public int minCut(String s) {
if(s==null ||s.length()==0){
return 0;
}
//制作状态表
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
int[] dp = new int[s.length()+1];//表示从0--i是否可以拆分成回文子串
dp[0] = 1;
ArrayList<Integer> list0 = new ArrayList<Integer>();
list0.add(-1);
list.add(list0);
for(int i=1;i<dp.length;i++){
ArrayList<Integer> temp = new ArrayList<Integer>();
for(int j=0;j<i;++j){
if(dp[j]==1 && isPalindrome(s.substring(j,i))){
dp[i] =1;
temp.add(j);
}
}
list.add(temp);
}
ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>();
ArrayList<String> curList = new ArrayList<String>();
// dfs(s,curList,list.size()-1,list,result);
//制作图
int[][] map = new int[s.length()+1][s.length()+1];
for(int i=0;i<map.length;i++){
for(int j=0;j<map.length;++j){
map[i][j] = Integer.MAX_VALUE;
}
}
for(int i=0;i<list.size();i++){
for(int j=0;j<list.get(i).size();++j){
if(list.get(i).get(j)>=0) map[i][list.get(i).get(j)] = 1;
}
}
ArrayList<Integer> minRoute = getTwoPointsRoute( map.length-1,0, map);
//System.out.println(minRoute.size()-2);
return minRoute.size()-3;
}
public static ArrayList<Integer> getTwoPointsRoute(int start,int end,int[][]map){
int cur = end;
int maxMapPoints = map.length;
int[] dist = new int[maxMapPoints];
int[] prev = new int[maxMapPoints];
int mapPoints = map.length;
if(start<0 || start>mapPoints || cur<0 || cur>mapPoints || prev[cur]==-1){
return null;
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
DijkstraMethod(start, dist, prev, map);
Stack<Integer> stack = new Stack<Integer>();
int cost = 0;
while(cur!=-1){
//System.out.print(cur+" ");
stack.add(cur);
cost += dist[cur];
cur = prev[cur];
}
//倒序
while(!stack.isEmpty()){
arrayList.add(stack.pop());
}
arrayList.add(cost);
return arrayList;
}
public static void DijkstraMethod(int v0,int[] dist,int[] prev,int[][]map){
int n = map.length;
boolean[] S = new boolean[map.length];//判断是否在S集合当中
//初始化
for(int i =0;i<n;i++){
dist[i] = map[v0][i];
S[i] = false;
if(dist[i]==Integer.MAX_VALUE){
prev[i]= -1;
}else{
prev[i] = v0;
}
}
dist[v0] = 0;
S[v0] = true;
//选出n-1个点到S中
for(int i=0;i<n-1;i++){
int mindist = Integer.MAX_VALUE;
int u = v0;
//从集合U当中找出一个最小距离的点j 下标存在u中 既dist[j]最小
for(int j=0;j<n;j++){
if(!S[j] && dist[j]<mindist){
u = j;
mindist = dist[j];
}
}
S[u] = true;
//更新所有U中的集合,如果v0经过u到U集合中点的距离小于直接到U的距离则更新
for(int j=0;j<n;++j){
if(!S[j] && map[u][j]<Integer.MAX_VALUE){
if(dist[u]+map[u][j]<dist[j]){
dist[j] = dist[u] +map[u][j];
prev[j] = u;
}
}
}
}
}
// public static void dfs(String s,ArrayList<String> curList,int cur,ArrayList<ArrayList<Integer>> list,ArrayList<ArrayList<String>> result){
// if(cur==0){
// Collections.reverse(curList);
// result.add(curList);
// return;
// }
//
// for(int i=list.get(cur).size()-1;i>=0;i--){
//
// int next = list.get(cur).get(i);
// ArrayList<String> temp = new ArrayList<String>();
// temp.addAll(curList);
// curList.add(s.substring(next,cur));
// temp.add(s.substring(next,cur));
// System.out.println("@"+cur+"@"+curList);
// dfs(s,temp,next,list,result);
// curList.remove(curList.size()-1);
// }
// }
public static boolean isPalindrome(String str){
if(str==null || str.length()==0){
return false;
}
for(int i=0,j=str.length()-1;i<=j;i++,j--){
if(str.charAt(i)!=str.charAt(j)) return false;
}
return true;
}
}