一、需求
- 给你一个字符串
s
,请你将s
分割成一些子串,使每个子串都是 回文串 ,返回s
所有可能的分割方案;
示例 1:
输入:s = "aab" 输出:[["a","a","b"],["aa","b"]]
提示:
1 <= s.length <= 16
s
仅由小写英文字母组成
二、DFS
2.1 思路分析
- 题目给定一个字符串,然后设计一个算法,将这个字符串分割成回文子串,将所有的分割方案存储的集合中并返回;
- 现在要分析,如何根据给定的字符串得到所有可能的分割方案呢?如下图所示:
3.根据上图可以发现,对于给定字符串,当字符串为空串时,将各个截取的字串合在一起就是一种分割方案,这样上图有两种方案:["a","a","b"],["aa","b"];
4.根据该图分析解决问题的思路:①使用栈来记录从根串到空串的路径,这样做的原因是方便回溯,最后添加的最先出去;②遍历字符串,假设当前索引为 i ,判断以索引 i 为结尾的子串是否为回文串,如果不是则遍历下一个字符,否则加当前回文串入栈,然后递归的执行起始索引 i 以后的字符串内容,执行结束后回溯;
2.2 代码实现
class Solution {
public List<List<String>> partition(String s) {
List<List<String>> res = new ArrayList<>();
if(s == null || s.length() == 0) {
return res;
}
Deque<String> path = new ArrayDeque<>();
char[] ch = s.toCharArray();
dfs(ch, path, res, 0);
return res;
}
/**
*该方法将所有分割方案添加到集合中
*@param ch 给定字符串的数组形式
*@param path 存储分割方案中的回文串
*@param res 存储所有的分割方案
*@param index 遍历字符串的索引
*/
public void dfs(char[] ch, Deque<String> path, List<List<String>> res, int index) {
if(index == ch.length) {
res.add(new ArrayList(path));
return;
}
for(int i = index; i < ch.length; i++) {
if(!palindrome(ch, index, i)) {
continue;
}
path.addLast(new String(ch, index, i-index+1));
dfs(ch, path, res, i + 1);
path.removeLast();
}
}
/**
*该方法用来判断是否为回文串
*@param ch 给定字符串的数组形式
*@param left 字符串的起始索引下标
*@param right 字符串的结束索引下标
*/
public boolean palindrome(char[] ch, int left, int right) {
while(left < right) {
if(ch[left] != ch[right]) {
return false;
}
left++;
right--;
}
return true;
}
}
2.3 复杂度分析
- 时间复杂度为,其中N为字符串字符的个数,最坏情况下,字符串中的字符全部相同时,那么字符串的划分方案数就有中,每一种划分都需要O(N)的时间来存储结果;
- 空间复杂度为O(N),其中返回值不作为空间消耗,若考虑返回值,则空间复杂度为;
三、学习地址
作者:liweiwei1419