131. Palindrome Partitioning && 132. Palindrome Partitioning II
131. Palindrome Partitioning
Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
For example, given s = "aab",
Return
[ ["aa","b"], ["a","a","b"] ]
public class Solution { public List<List<String>> partition(String s) { List<List<String>> results = new ArrayList<List<String>>(); partition(s, results, new LinkedList<String>(), 0); return results; } private void partition(String s, List<List<String>> results, Deque<String> current, int from) { if(from>=s.length()){ results.add(new ArrayList<String>(current)); return; } for(int i = from; i<s.length(); ++i){ if(isPalindrom(s, from, i)){ current.add(s.substring(from, i+1)); partition(s, results, current, i+1); current.removeLast(); } } } //[from, to] private boolean isPalindrom(String s, int from, int to){ while(from<=to) if(s.charAt(from++) != s.charAt(to--)) return false; return true; } }
132. 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.
Adapt the solution to Longest Palindromic Substring, you can easily get a TLE solution.
public class Solution { public int minCut(String s) { int[] longest = longestPalindrome(s); if (longest[1] == s.length()) return 0; if (longest[0] == 0) //e.g. minCut("aab") = 1+minCut("b") return 1 + minCut(s.substring(longest[1])); if (longest[0] + longest[1] == s.length()) //e.g. minCut("abb") = 1+minCut("a") return 1 + minCut(s.substring(longest[0])); //e.g. minCut("abbbc") = 2+minCut("a")+minCut("c") return 2 + minCut(s.substring(0, longest[0])) + minCut(s.substring(longest[0] + longest[1])); } //returns int[]{resultBegin, resultLen} private int[] longestPalindrome(String s) { int len = s.length(); if (len < 2) return new int[]{0, len}; int[] result = new int[]{0, 0}; for (int center = 0; center < len - 1; ++center) { extendBothEnds(s, center, center, result); //when longestPalindrome length is odd extendBothEnds(s, center, center + 1, result); //when longestPalindrome length is even } return result; } private void extendBothEnds(String s, int left, int right, int[] result) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { --left; ++right; } ++left; --right; int currentLen = right - left + 1; if (currentLen > result[1]) { result[1] = currentLen; result[0] = left; } } }
DP solution:
Use a table isPalindrome to denote whether s.substring(row, column+1) is a palindrome.
We can save the work of checking palindrome for new substring by doing
isPalindrome[row][column] = (s.charAt(row) == s.charAt(column)) && isPalindrome[row+1][column-1]
public class Solution { public int minCut(String s) { char[] c = s.toCharArray(); int n = c.length; //minCuts keep the minimum cut for s.substring[0,i] //default values are 0,1,2,3,4... int[] minCuts = new int[n]; boolean[][] isPalindrome = new boolean[n][n]; for (int end = 0; end < n; ++end) { int min = end; //set the default value for (int begin = 0; begin <= end; ++begin) { if (c[begin] == c[end] && (begin + 1 > end - 1 || isPalindrome[begin + 1][end - 1])) { isPalindrome[begin][end] = true; if (begin == 0) min = 0; else min = Math.min(min, minCuts[begin - 1] + 1);//add 1 more cut after s.substring[0,begin-1] } } minCuts[end] = min; } return minCuts[n - 1]; } }

浙公网安备 33010602011771号