132. Palindrome Partitioning II
一、题目
1、审题
2、分析
给出一个字符串,将其切割后分成的子串全为回文,求最少切几刀。
二、解答
1、思路:
方法一
采用一个 DP 数组记录。
DP[i]:表示到达下标 i 需要切的刀数。
public int minCut2(String s) { int n = s.length(); if (s == null || n <= 1) { return 0; } int[] dp = new int[n]; for (int i = 0; i < n; i++) dp[i] = i; for (int i = 0; i < n; i++) { // CASE 1. odd len: center is at index i, expand on both sides for(int start = i, end = i; start >= 0 && end < n && s.charAt(start) == s.charAt(end); start--, end++) { int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1; // start == 0,则 第一步就能到 end dp[end] = Math.min(dp[end], newCutAtEnd); } // CASE 2: even len: center is between [i-1, i], expand on both sides for(int start = i - 1, end = i; start >= 0 && end < n && s.charAt(start) == s.charAt(end); start--, end++) { int newCutAtEnd = (start == 0) ? 0 : dp[start - 1] + 1; dp[end] = Math.min(dp[end], newCutAtEnd); } } return dp[n - 1]; }
方法二:
采用两个动态数组。
pal[j][i] = true: 从下标 j 到下标 i 是回文。
cut[i] = n: 到达下标 i 至少需要切 n 刀。
public int minCut(String s) { char[] c = s.toCharArray(); int n = c.length; int[] cut = new int[n]; boolean[][] pal = new boolean[n][n]; for (int i = 0; i < n; i++) { int min = i; for (int j = 0; j <= i; j++) { if(c[j] == c[i] && (i - j <= 2 || pal[j+1][i-1])) { pal[j][i] = true; // 从 j 到 i min = (j == 0) ? 0 : Math.min(min, cut[j-1] + 1); } } cut[i] = min; } return cut[n - 1]; }