DP動態規劃專題六 :LeetCode 132. Palindrome Partitioning II
阿新 • • 發佈:2018-12-30
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.
Example:
Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
我們依舊沿襲palindrome partinioning的思路,可以推出這道題,但是時間複雜度比較高,為nn
解法一:
public int minCut(String s) { if (s.length() <= 1) return 0; int[] dp = new int[s.length()]; for (int i = 1; i < s.length(); i++) { int min = Integer.MAX_VALUE; for (int p = 1; p <= i; p++) { if (isPalindrome(s.substring(p, i+1))) { min= Math.min(min, dp[p-1] + 1); } } dp[i] = min; if (isPalindrome(s.substring(0, i+1))) { dp[i] = 0; } } return dp[s.length() - 1]; } private boolean isPalindrome(String s) { if (s.length() <= 1) return true; int l = 0; int r = s.length() - 1; while (l < r) { if (s.charAt(l++) != s.charAt(r--)) { return false; } } return true; }
解法二:由於abbba是palindrome,因此bbb也一定是,ab不是,那麼cabc也一定不是,所以我們可以先用一個二維陣列來儲存從i到j是否是palindrome,然後ispal的時候直接看陣列就能得到答案,這樣可以減少對ispal函式的呼叫來優化時間。
public int minCut(String s) { //todo: sanity checks if (s == null || s.length() == 0) return 0; //沒有長度為0 的字元: off by one boolean[][] dp = new boolean[s.length()][ s.length()]; //base case dp[0][0] = true; int[] mins = new int[s.length()]; mins[0] = 0; for (int i = 1; i < s.length(); i++) { int local = i ; //每個位置都切。 我們要求最小,所以給個大一點的值 for (int j = 0; j <= i; j++) { char cj = s.charAt(j); char ci = s.charAt(i); if ( cj == ci &&(i - j < 2 || dp[j + 1] [i - 1])){ dp[j][i] = true; local = j == 0 ? 0 : Math.min(local, mins[j-1] + 1); } } mins[i] = local; } return mins[s.length() - 1]; }