给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例 2:
输入:s = “a”
输出:[[“a”]]
来源:力扣(LeetCode)
package 回溯;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class 分割回文串
{
static LinkedList<String>list = new LinkedList<>();
static List<List<String>> res = new ArrayList<>();
public static void main(String[] args) {
System.out.println(partition("leet"));
}
public static List<List<String>> partition(String s) {
backtracking(s, 0);
return res;
}
public static void backtracking(String s,int startindex)
{
if(startindex==s.length())//当切割线在最后一个字符后面说明就已经没有了,
{
res.add(new ArrayList<>(list));
return;
}
for(int i=startindex;i<s.length();i++)
{
String str=s.substring(startindex,i+1);
if(isPalindrome(str))
{
list.add(str);
}
else
{
continue;
}
backtracking(s,i+1);//这i+1前面切割过的就不用再切割了
list.removeLast();
}
}
//判断回文数
public static boolean isPalindrome(String s)
{
if(s.length()==1)
{
return true;
}
boolean flag=false;
for(int i=0;i<s.length()/2;i++)
{
if(s.charAt(i)==s.charAt(s.length()-i-1))
{
flag=true;
continue;
}
return false;
}
return flag;
}
}
同样这道题目也是用回溯来做,但是我一开始也没有什么思路,只知道用回溯,甚至连题目中的切割怎么切都不是很清楚。
看了代码随想录后,才明白其实就是一个类似组合问题的切割问题
首先做回溯题目还是离不开先手画一个N叉树
例如
我们把切割线的左边假设去掉,其实有点类似于组合问题了
第二层就变成 ab ,b,空
第三层就变成b,空,空空
也可以理解每一层截取的字符不断增加 从1个到3个
直到截取的位置超越最后一个字符的位置
这里还有截取字符的时候还有一个比较难理解的点比如截取的时候
代码是:
public static void backtracking(String s,int startindex)
{
if(startindex==s.length())//当切割线在最后一个字符后面说明就已经没有了,
{
res.add(new ArrayList<>(list));
return;
}
for(int i=startindex;i<s.length();i++)
{
String str=s.substring(startindex,i+1);
if(isPalindrome(str))
{
list.add(str);
}
else
{
continue;
}
backtracking(s,i+1);//这i+1前面切割过的就不用再切割了
list.removeLast();
}
}
这个stateindex是在每一层是不变的,因为截取的个数再变大,从a,aa,aab 只有到下一层这个startindex才会增加。