132.Palindrome Partitioning II

題目連接數組

題目大意:給出一個字符串,對其進行劃分,造成全部子串是迴文串,找出最小須要劃分的次數。好比字符串"aab",最小的劃分次數是1,造成"aa","b",都是迴文串。ide

法一:利用131題的DFS,超時。代碼以下:spa

 1     private static int dfs(String s, int res, int start, ArrayList<String> tmp) {
 2         //若是找到一種劃分狀況,則將其接入結果集中
 3         if(start == s.length()) {
 4             if(tmp.size() - 1 < res) {
 5                 res = tmp.size() - 1;
 6             }
 7             return res;
 8         }
 9         //尋找每個可能的迴文字符串
10         for(int i = start; i < s.length(); i++) {
11             //判斷字符串的其中一個子串,若是是迴文
12             if(isPalindrome(s, start, i) == true) {
13                 //將這個迴文子串加入結果中,記住substring(start,end),是從start到end-1的字符串。
14                 tmp.add(s.substring(start, i + 1));
15                 //注意,下次劃分的子串起始點應該是i+1,由於i已經在上一個子串中了
16                 res = dfs(s, res, i + 1, tmp);
17                 //回溯移除
18                 tmp.remove(tmp.size() - 1);
19             }
20         }
21         return res;
22     }
23     //判斷迴文
24     private static boolean isPalindrome(String s, int start, int end) {
25         while(start <= end) {
26             if(s.charAt(start) != s.charAt(end)) {
27                 return false;
28             }
29             start++;
30             end--;
31         }
32         return true;
33     }
View Code

法二:用到了5題的DP,就是利用DP求解迴文子字符串的問題,可是這題還擴展了,不只求解迴文子串,還要求解最小分割數,使得全部子串都是迴文串,好比"aab",最後的DP數組就是,dp[0][0],dp[1][1],dp[2][2],這是一次分割;dp[0][1],dp[2][2],這是一次分割。能夠看出dp[i][j]就是表明i到j的字符串是不是迴文串,而後根據dp數組,再計算分割數。爲了節約時間,二者放在一塊兒同時計算,而分割數的dp方程是mi[i] = Math.min(mi[i], mi[j + 1] + 1)。mi[i]表示i到n-1的字符串須要分割的最小次數。代碼以下(耗時20ms):3d

 1     public int minCut(String s) {
 2         //dp[i][j]表示在i到j之間的字符串是不是迴文串
 3         boolean[][] dp = new boolean[s.length()][s.length()];
 4         for(int i = 0; i < s.length(); i++) {
 5             dp[i][i] = true;
 6         }
 7         //mi[i]表示i到n-1之間的字符串最小須要分割的次數
 8         //從後往前計算
 9         int[] mi = new int[s.length() + 1];
10         for(int i = s.length() - 1; i >= 0; i--) {
11             mi[i] = Integer.MAX_VALUE;//初始化在i的後面分割一下
12             for(int j = i; j < s.length(); j++) {
13                 if(s.charAt(i) == s.charAt(j) && (j - i <= 1 || dp[i + 1][j - 1] == true)) {
14                     dp[i][j] = true;
15                     //由於i到j構成迴文串,因此能夠考慮在j後面分割,而後與在i後面分割進行比較
16                     mi[i] = Math.min(mi[i], 1 + mi[j + 1]);
17                 }
18             }
19         }
20         return mi[0] - 1;
21     }
View Code
相關文章
相關標籤/搜索