给你一个字符串 s
,请你将 s
分割成一些子串,使每个子串都是回文。
返回符合要求的 最少分割次数 。
示例 1:
输入:s = "aab" 输出:1 解释:只需一次分割就可将 s 分割成 ["aa","b"] 这样两个回文子串。
示例 2:
输入:s = "a" 输出:0
示例 3:
输入:s = "ab" 输出:1
提示:
1 <= s.length <= 2000
s
仅由小写英文字母组成
use backtrack solution from131. 分割回文串, oops, get tle and sle
class Solution: def minCut(self, s: str) -> int: res=[] def helper(s,tmp): if not s: res.append(tmp)#空字符说明处理完毕 for i in range(1,len(s)+1): if s[:i]==s[:i][::-1]:#判断回文 helper(s[i:],tmp+[s[:i]])#回溯 helper(s,[]) return min(len(x)-1 for x in res)
class Solution { public int minCut(String s) { List<List<String>> list = new ArrayList<>(); backtrack(list, new ArrayList<>(), s, 0); int ans=2010; for(int i=0;i<list.size();i++){ ans=Math.min(list.get(i).size(),ans); } return ans-1; } public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){ if(start == s.length()) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < s.length(); i++){ if(isPalindrome(s, start, i)){ tempList.add(s.substring(start, i + 1)); backtrack(list, tempList, s, i + 1); tempList.remove(tempList.size() - 1); } } } } public boolean isPalindrome(String s, int low, int high){ while(low < high) if(s.charAt(low++) != s.charAt(high--)) return false; return true; } }
now we have to come up with a DP solution
The idea is that if c[j+1] to c[i-1] is the number of palindromes and there is c[j]==c[i], then the number of palindromes is extended. Pal[j][i]=true means that c[j] to c[i] are the number of palindromes.
Time complexity O(n^2)
Space complexity O(n^2)
class Solution { 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] && (j+1 > i-1 || pal[j+1][i-1])){ pal[j][i]=true; min = j == 0 ? 0 : Math.min(min, cut[j - 1] + 1); } } cut[i] = min; } return cut[n-1]; } }