给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a"
输出:[["a"]]
提示:
1 <= s.length <= 16s 仅由小写英文字母组成
解题思路:
回文串是正着倒着看都一样的字符串,因为不考虑空格的情况,所以判断回文串的方法可以简单地写成:
function isReverse(s) {
return s.split('').reverse().join('') === s;
}
接下来就是要判断原字符串的子字符串哪些是回文串。我们可以穷举出所有的字符串逐个判定,但是这样子在对很长的字符串的时候,穷举出的子字符串的数量会非常大,无疑会超时。
我们可以从一个开始的节点去深度搜索来找。即尽量取一个字符串的前面部分最长的字串来切割,然后剩余的部分再递归这个方法。当找到最长的一个子串作为头部是回文串的话,才接着递归取找剩余的部分。不然就把头部的长度减少看看。最坏的情况头部减到1的话就必然是回文串。然后在每个长度作为头部深度优先取找可能性,如果能分割完原字符串,就代表找到了一个结果
具体代码如下:
var partition = function(s) {
const result = [];
function isReverse(s) {
return s.split('').reverse().join('') === s;
}
function Dp(before, s) {
if(!s) result.push(before); //如果能找完整个字符串,就添加结果。
for(let i=0;i<s.length;i++) {
const head = s.slice(0, s.length-i);
if (isReverse(head)) Dp(before.concat([head]), s.slice(s.length-i))}; //如果前面的字串是回文,就递归找剩余的部分。
}
Dp([], s);
return result;
};
总结
在考虑某种前置条件成立,才可能后面部分成立的情况下,可以用深度优先搜索,在遇到不符合条件的情况下及时返回,减少运算量
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情