[LeetCode:Palindrome Partitioning] | 刷题打卡

359 阅读1分钟

题目描述

给你一个字符串 s,返回 s 的所有回文部分字串(把 s 给拆分成多个部分,每个部分都是一个回文串)

例一:

输入: s = "aab"
输出: [["a","a","b"],["aa","b"]]

例二:

输入: s = "a"
输出: [["a"]]

思路分析

不难看出,这又是一道回溯题,对于字符串 "aab" 来说,我们可以现在脑海中模拟一下回溯的过程:

  1. 从左往右取长度为 1 的字串 "a","a" 是回文,把 "a" 加入到已经选择的列表,继续递归剩下的部分 "ab"
  2. 对 "ab" 进行和步骤 1 同样的过程,取出 "a" 剩余 "b",取出 "ab",剩余空字符串
  3. 判断每次取出的字符串,如果是回文的话,才会进行假如已选列表,并执行递归过程,否则放弃掉
  4. 重复上述过程...

我们先写出判断是否是回文的代码:

const isPalindrome = (str) => {
  if (str.length === 0) {
    return false;
  }
  for (let i = 0, j = str.length - 1; i < j; i++, j--) {
    if (str[i] !== str[j]) {
      return false;
    }
  }
  return true;
};

然后是我们的回溯代码:

初始化时:

  • 待选集合是字符串 s
  • 已选的集合为空

递归的过程:

  1. 遍历待选字符串,分别取出长度为 1,2,3...s.length 的回文子串
  2. 把当前取出的回文串加入到已选集合中
  3. 剩下的串继续执行递归过程

递归出口:待选字符串为空时停止,将已选的集合 push 到结果数组中

AC 代码

var partition = function (s) {
  let result = [];
  const backtrace = (str, current) => {
    if (str === "") {
      result.push(current);
      return;
    }
    for (let i = 1; i <= str.length; i++) {
      let arr = [...current];
      let subStr = str.slice(0, i);
      if (isPalindrome(subStr)) {
        arr.push(subStr);
        backtrace(str.slice(i), arr);
      } else {
        continue;
      }
    }
  };
  backtrace(s, []);
  return result;
};

总结

这道题和

这四道题都用到了回溯算法,大家可以放在一起作比较,理解回溯算法的写法和思路,最终总结出一套属于自己的方法论。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情