题目地址(131. 分割回文串)
https://leetcode-cn.com/problems/palindrome-partitioning/
题目描述
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。回文串 是正着读和反着读都一样的字符串。示例 1:输入:s = "aab"输出:[["a","a","b"],["aa","b"]]示例 2:输入:s = "a"输出:[["a"]]提示:1 <= s.length <= 16s 仅由小写英文字母组成
前置知识
公司
- 暂无
思路
本题这涉及到两个关键问题:
- 切割问题,有不同的切割方式
- 判断回文
其实切割问题类似组合问题。
例如对于字符串abcdef:
- 组合问题:选取一个a之后,在bcdef中再去选取第二个,选取b之后在cdef中在选组第三个…..。
- 切割问题:切割一个a之后,在bcdef中再去切割第二段,切割b之后在cdef中在切割第三段…..。

判断回文子串
最后我们看一下回文子串要如何判断了,判断一个字符串是否是回文。
可以使用双指针法,一个指针从前向后,一个指针从后先前,如果前后指针所指向的元素是相等的,就是回文字符串了。
关键点
- 怎么判断是不是回文串
- 双指针对向遍历
- 递归如何终止
- 起始位置大于s的大小
代码
- 语言支持:Java
Java Code:
class Solution {ArrayList<List<String>> res = new ArrayList<>();ArrayList<String> path = new ArrayList<>();// Deque<String> path = new LinkedList<>();public List<List<String>> partition(String s) {loop(s,0);return res;}void loop(String s , int startIndex){//终止条件 如果起始位置已经大于s的大小,说明已经找到了一组分割方案了if (startIndex >= s.length()) {res.add(new ArrayList<>(path));return;}//从0开始 循环数组长度次for (int i = startIndex; i < s.length() ; i++) {//判断是不是回文数 如果是 就把当前的与层数对应的字符串截取 然后添加到路径//如果不是 就跳过当次循环 第一次碰到就是把单个字符判断成回文串 递归回来在判断后面的if (judge(s, startIndex, i)) {path.add(s.substring(startIndex, i+1));}else {continue;}//递归 下一层由i+1来作为startIndexloop(s,i+1);//回溯 递归后返回将最后一个数删了path.remove(path.size()-1);}}//使用双指针 从前后分别遍历 如果遇到不相等的情况就返回false 其他都为trueboolean judge(String s,int start , int end){for (int i = start , j = end ; i < j ; i++ , j--) {if (s.charAt(i) != s.charAt(j)) {return false;}}return true;}}
复杂度分析
令 n 为数组长度。
- 时间复杂度:
#card=math&code=O%28n%29&id=ffdK2)
- 空间复杂度:
#card=math&code=O%28n%29&id=u5hWn)
