[leetcode] Palindrome Partitioning II
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab"
,
Return 1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
https://oj.leetcode.com/problems/palindrome-partitioning-ii/
思路:DP。cuts[i]表示从i到结尾的子串,要达到题意需要的最少切割数。isPalin用来判断是否是palindrome。
初始化:cuts[i]=len-i
推倒:cuts[i]=true if s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])
推倒的同时求出isPalin数组的值,提高效率。
public class Solution {
public int minCut(String s) {
if (s == null || s.length() == 0)
return 0;
int len = s.length();
boolean[][] isPalin = new boolean[len][len];
int[] cuts = new int[len + 1];
for (int i = 0; i < len; i++)
cuts[i] = len - i;
for (int i = len - 1; i >= 0; i--) {
for (int j = i; j < len; j++) {
if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) {
isPalin[i][j] = true;
cuts[i] = Math.min(cuts[i], cuts[j + 1] + 1);
}
}
}
return cuts[0] - 1;
}
public static void main(String[] args) {
System.out.println(new Solution().minCut("bb"));
}
}
第二遍记录:注意DP的出事状态和递推关系,与第一遍解法不同,dp[i]代表s[0..i]的最小分割数,需要根据当前元素是否与之前元素组成回文不断更新最小值。
public int minCut(String s) { if (s == null || s.length() == 0) return 0; int len = s.length(); boolean[][] isPalin = new boolean[len][len]; int[] cuts = new int[len + 1]; for (int i = 0; i <= len; i++) cuts[i] = i; for (int i = len - 1; i >= 0; i--) { for (int j = i; j < len; j++) { if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) { isPalin[i][j] = true; } } } for (int i = 1; i <= len; i++) {for (int j = 1; j <= i; j++) { if (isPalin[j - 1][i - 1]) { cuts[i] = Math.min(cuts[i], cuts[j - 1] + 1); } } } return cuts[len] - 1; }
第三遍记录:
dp[i]代表s[0..i]的最小分割数
注意dp数组初始状态
先用二位dp求出isPalin数组用于后面快速查询
/** * s: abaab minCut:2 "" a b a a b b dp -1 0 1 0 1 2 2 init -1 0 1 2 3 4 5 * */ public class Solution { public int minCut(String s) { if (s == null || s.length() <= 1) return 0; int n = s.length(); int[] dp = new int[n + 1]; for (int i = 0; i <= n; i++) dp[i] = i - 1; boolean[][] isPalin = new boolean[n][n]; for (int i = n - 1; i >= 0; i--) { for (int j = i; j < n; j++) { if (s.charAt(i) == s.charAt(j) && (j - i < 2 || isPalin[i + 1][j - 1])) { isPalin[i][j] = true; } } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { if (isPalin[j - 1][i - 1]) { dp[i] = Math.min(dp[j - 1] + 1, dp[i]); } } } return dp[n]; } public static void main(String[] args) { System.out.println(new Solution().minCut("abababab")); } }
参考: