palindrome-partitioning-ii

题目连接

思路

  1. 通过动态规划制作一个点i 之前能够分割的所有点j
  2. 把这些关系想象为有向图
  3. 计算最后一个节点到点0的最短路径-2 最短路径用dijkstra算法
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;
     }

}

你可能感兴趣的:(LeetCode)