文章目录
分割回文串
示例 1:
输入:s = "aab"
输出:[["a","a","b"],["aa","b"]]
示例 2:
输入:s = "a"
输出:[["a"]]
思路一:回溯法
function isPalindrome(str) {
let left = 0, right = str.length - 1;
while (left < right) {
if (str[left] !== str[right]) {
return false;
}
left++;
right--;
}
return true;
}
function partition(s, start = 0, path = [], result = null) {
if (result === null) {
result = [];
}
if (start === s.length) {
result.push([...path]);
return result;
}
for (let i = start; i < s.length; i++) {
if (isPalindrome(s.slice(start, i + 1))) {
path.push(s.slice(start, i + 1));
partition(s, i + 1, path, result);
path.pop(); // 回溯
}
}
return result;
}
function partitionPalindromes(s) {
return partition(s);
}
思路二:动态规划
var partition = function (s) {
const n = s.length;
const dp = Array.from({ length: n }, () => Array(n).fill(false));
const result = [];
// 预处理回文
for (let end = 0; end < n; end++) {
for (let start = end; start >= 0; start--) {
if (s[start] === s[end] && (end - start <= 2 || dp[start + 1][end - 1])) {
dp[start][end] = true;
}
}
}
function backtrack(start, path) {
if (start === n) {
result.push([...path]);
return;
}
for (let end = start; end < n; end++) {
if (dp[start][end]) {
path.push(s.slice(start, end + 1));
backtrack(end + 1, path);
path.pop();
}
}
}
backtrack(0, []);
return result;
};
方法三:记忆化搜索
function isPalindrome(str) {
return str === str.split('').reverse().join('');
}
function partition(s) {
const result = [];
const memo = {};
function backtrack(start, path) {
if (start === s.length) {
result.push([...path]);
return;
}
for (let end = start + 1; end <= s.length; end++) {
const substring = s.slice(start, end);
if (memo[substring] === undefined) {
memo[substring] = isPalindrome(substring);
}
if (memo[substring]) {
path.push(substring);
backtrack(end, path);
path.pop();
}
}
}
backtrack(0, []);
return result;
}
方法四:迭代法
function partition(s) {
const result = [];
const stack = [[0, []]];
while (stack.length) {
const [start, path] = stack.pop();
if (start === s.length) {
result.push(path);
continue;
}
for (let end = start + 1; end <= s.length; end++) {
const substring = s.slice(start, end);
if (substring === substring.split('').reverse().join('')) {
stack.push([end, [...path, substring]]);
}
}
}
return result;
}
方法五:位运算
function isPalindrome(str) {
return str === str.split('').reverse().join('');
}
function partition(s) {
const n = s.length;
const result = [];
const totalCombinations = 1 << n; // 2^n
for (let i = 0; i < totalCombinations; i++) {
const path = [];
let lastIndex = 0;
for (let j = 0; j < n; j++) {
if (i & (1 << j)) {
const substring = s.slice(lastIndex, j + 1);
if (isPalindrome(substring)) {
path.push(substring);
lastIndex = j + 1;
}
}
}
if (lastIndex === n) {
result.push(path);
}
}
return result;
}