LeetCode 132. Palindrome Partitioning II
原题链接在这里:https://leetcode.com/problems/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.
题解:
求的是至少切几刀能全是palindrome.
Let dp[j] denotes up to i 最少 能分成几块palindrome.
For all 0 <= i <= j 如果[i,j]段是palindrome, 到j点结束那段就可以从 到i点结束那段+1 来跟新最小值.
初始化至少每个字母都分开肯定都是palindrome了.
答案dp[n]-1. 最少分成的块数 比切的刀数 多一.
用二维array来matain [i, j]段是否是palindrome. 两边闭区间,包括i,j对应的char. This could hep reduce running time from O(n^3) to O(n^2).
Time Complexity: O(n^2). n = s.length().
Space: O(n^2).
AC Java:
1 class Solution { 2 public int minCut(String s) { 3 if(s == null || s.length() == 0){ 4 return 0; 5 } 6 7 int n = s.length(); 8 boolean [][] isPal = preCal(s); 9 int [] dp = new int[n+1]; 10 11 for(int j = 0; j<n; j++){ 12 dp[j+1] = j+1; 13 for(int i = 0; i<=j; i++){ //error 14 if(isPal[i][j]){ 15 dp[j+1] = Math.min(dp[j+1], dp[i]+1); 16 } 17 } 18 } 19 20 return dp[n]-1; 21 } 22 23 private boolean [][] preCal(String s){ 24 int n = s.length(); 25 boolean [][] res = new boolean[n][n]; 26 for(int j = 0; j<n; j++){ 27 for(int i = j; i>=0; i--){ 28 if(s.charAt(i) == s.charAt(j) && (j-i<2 || res[i+1][j-1])){ //error 29 res[i][j] = true; 30 } 31 } 32 } 33 34 return res; 35 } 36 }
对每一个点按照奇数和偶数两种方式 左右延展若是palindrome就更新dp array. 若不是就停止.
Note: initialize dp[0] as -1. e.g. "aa", dp[2] = dp[0] + 1 = 0.
Time Complexity: O(n^2).
Space: O(n).
AC Java:
1 class Solution { 2 public int minCut(String s) { 3 if(s == null || s.length() == 0){ 4 return 0; 5 } 6 7 int len = s.length(); 8 int [] dp = new int[len+1]; 9 for(int i = 0; i<=len; i++){ 10 dp[i] = i-1; 11 } 12 for(int i = 0; i<len; i++){ 13 // odd length palindrome 14 for(int l = i, r = i; l>=0 && r<len && s.charAt(l)==s.charAt(r); l--, r++){ 15 dp[r+1] = Math.min(dp[r+1], dp[l]+1); 16 } 17 18 // even length palindrome 19 for(int l = i, r = i+1; l>=0 && r<len && s.charAt(l)==s.charAt(r); l--, r++){ 20 dp[r+1] = Math.min(dp[r+1], dp[l]+1); 21 } 22 } 23 return dp[len]; 24 } 25 }
类似Word Break.