131.分割回文串
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]
这题真的很难
555555555
一开始我做了四小时,只能通过部分测例,我的思路是每次截取 len 长度,len<s.length() ,len++。最后没做出来,题解也是看了好多遍才一知半解。题解的思路:
递归+回溯
我好像说了句废话
这里是 分割线 移动,当分割线的位置 >=s.length(),意味着一次的在原来的基础上的字符串分割一轮结束。
然后递归回原来的基础,基础再变,再以此为基础再移动分割线。直到整个字符串变成了基础。
package com.programmercarl.backtracking;
import java.util.*;
/**
* @ClassName Partition
* @Descriotion TODO
* @Author nitaotao
* @Date 2022/7/10 9:42
* @Version 1.0
* https://leetcode.cn/problems/palindrome-partitioning/
* 131. 分割回文串
**/
public class Partition {
public static void main(String[] args) {
System.out.println(new Partition().partition("aab"));
}
//结果集
List<List<String>> result = new ArrayList<>();
//每次分割到最后时的一轮结果集
Stack<String> stack = new Stack();
public List<List<String>> partition(String s) {
backtracking(s, 0);
return result;
}
/**
*
* @param s 源字符串
* @param splitIndex 当前分割位置
* 思路
* aab
* a
* a
* b
* aa
* b
*/
public void backtracking(String s, int splitIndex) {
//每轮的终止条件: 分割线移动到s的后面了
if (splitIndex >= s.length()) {
result.add(new ArrayList(stack));
return;
}
for (int i = splitIndex; i < s.length(); i++) {
//通过splitIndex和i+1分割每次的字符串
if (isPartition(s, splitIndex, i + 1)) {
stack.push(s.substring(splitIndex, i + 1));
} else {
continue;
}
//此处加1是为了原来的位置不再被使用
//递归
backtracking(s, i + 1);
//回溯每次结果
stack.pop();
}
}
/**
* 判断当前字符串指定范围是否是回文字符串
* @param s
* @param startIndex
* @param endIndex
* @return
*/
public boolean isPartition(String s, int startIndex, int endIndex) {
while (startIndex < endIndex) {
if (s.charAt(startIndex) != s.charAt(endIndex-1)) {
return false;
}
startIndex++;
endIndex--;
}
return true;
}
}