分割回文串
- https://leetcode.cn/problems/palindrome-partitioning/description/
描述
- 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串
- 返回 s 所有可能的分割方案
示例 1
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2
输入:s = "a"
输出:[["a"]]
提示
- 1 <= s.length <= 16
- s 仅由小写英文字母组成
Typescript 版算法实现
1 ) 方案1: 回溯 + 动态规划预处理
function partition(s: string): string[][] {const n = s.length;const f = new Array(n).fill(0).map(() => new Array(n).fill(true));let ret = [], ans = [];for (let i = n - 1; i >= 0; --i) {for (let j = i + 1; j < n; ++j) {f[i][j] = (s[i] === s[j]) && f[i + 1][j - 1];}}const dfs = (i) => {if (i === n) {ret.push(ans.slice());return;}for (let j = i; j < n; ++j) {if (f[i][j]) {ans.push(s.slice(i, j + 1));dfs(j + 1);ans.pop();}}}dfs(0);return ret;
};
2 ) 方案2: 回溯 + 记忆化搜索
function partition(s: string): string[][] {// 记忆化搜索中,f[i][j] = 0 表示未搜索,1 表示是回文串,-1 表示不是回文串const isPalindrome = (i, j) => {if (f[i][j] !== 0) {return f[i][j];}if (i >= j) {f[i][j] = 1;} else if (s[i] === s[j]) {f[i][j] = isPalindrome(i + 1, j - 1);} else {f[i][j] = -1;}return f[i][j];}const n = s.length;const ret = [], ans = [];const f = new Array(n).fill(0).map(() => new Array(n).fill(0));const dfs = (i) => {if (i === n) {ret.push(ans.slice());return;}for (let j = i; j < n; ++j) {if (isPalindrome(i, j) === 1) {ans.push(s.slice(i, j + 1));dfs(j + 1);ans.pop();}}}dfs(0);return ret;
};