同下
搜索 + 回溯的方法枚举所有可能的分割方法并进行判断。
有个例子,方便我们理解流程,已知字符串为"googoo"
var arr = new Array(n).fill(0).map(() => new Array(n).fill(true));构建二位数组模型,二位数组,只有右上角的数据有效,且它的意思是,为true说明,到该行红色元素是一个回文子串,例如第二行,最后一列的元素为true,他的位置到第二行红色true的位置对应的子串为"oogoo",它的布尔型由两个条件决定s[i] === s[j] && arr[i + 1][j - 1];,回文字符串要满足首位字符相等且中间部分也是回文字符串,而arr[i + 1][j - 1]代表的就是中间部门的回文子串的布尔性
for (var i = n - 2; i >= 0; i--) { 从倒数第二行开始,直到第一行
for (var j = i + 1; j < n; j++) { 从倒数第二行,最后一个元素开始,如上图箭头所示
arr[i][j] = s[i] === s[j] && arr[i + 1][j - 1]; [i,j]子串,是否是回文子串
for (var j = i; j < n; j++) { 搜索 + 回溯
brr.push(s.slice(i, j + 1));子串入栈
dfs(j + 1);继续搜索j+1之后的字符串的子串方案
res.push(brr.slice()); 子串已经到最后一个了,就存放一种结果
brr.pop();出栈回溯
var partition = function (s) {
var n = s.length;
var arr = new Array(n).fill(0).map(() => new Array(n).fill(true));
var res = [];
var brr = [];
for (var i = n - 2; i >= 0; i--) {
for (var j = i + 1; j < n; j++) {
arr[i][j] = s[i] === s[j] && arr[i + 1][j - 1];
}
}
dfs(0);
return res;
function dfs(i) {
if (i === n) {
res.push(brr.slice());
return;
}
for (var j = i; j < n; j++) {
if (arr[i][j]) {
brr.push(s.slice(i, j + 1));
dfs(j + 1);
brr.pop();
}
}
}
};
console.log(partition("google"));
更加简单的方法
function partition(s) {
var res = [];
var arr = [];
f(0);
return res;
function f(j) {
if (j === s.length) {
return res.push([...arr]);
}
let str = "";
for (let i = j; i < s.length; i++) {
str += s[i];
if (str !== [...str.split("")].reverse().join("")) continue;
arr.push(str);
f(i + 1);
arr.pop();
}
}
}