131. 分割回文串

96 阅读1分钟

131. 分割回文串

同下

剑指 Offer II 086. 分割回文子字符串

搜索 + 回溯的方法枚举所有可能的分割方法并进行判断。

有个例子,方便我们理解流程,已知字符串为"googoo"

image.png

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();
    }
  }
}