难度:中等
题目:
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是
回文串。返回 s 所有可能的分割方案。
示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]]
示例 2:
输入:s = “a”
输出:[[“a”]]
提示:
- 1 <= s.length <= 16
- s 仅由小写英文字母组成
解题思路:
使用回溯结合简单的回文检测来解决
- 定义辅助函数 isPalindrome:
- 这个函数用于判断一个字符串是否为回文串。
- 使用两个指针分别从字符串的头部和尾部向中心移动并比较字符是否相等。
- 定义递归函数 partition:
- 参数包括:
■ s: 原始输入字符串。
■ start: 当前处理的子串起始位置。
■ path: 用于存储当前递归路径上的回文子串。
■ result: 最终结果数组,用于收集所有满足条件的分割方案。 - 终止条件:当 start 等于字符串长度时,将 path 加入到结果数组 result 中。
- 递归逻辑:
- 遍历从 start 到字符串末尾的所有位置 i。
- 如果从 start 到 i 的子串是回文串,则将其加入到 path 中。
- 对剩余的字符串(从 i+1 开始)继续执行相同的操作。
- 在递归结束后,从 path 中移除刚刚添加的子串,进行回溯。
- 调用 partition 函数:
- 在主函数 partitionPalindromes 中,直接调用 partition 函数,无需额外参数,因为默认值已经设置好。
JavaScript 实现
// 判断是不是回文串
function isPalindrome(str) {
let left = 0, right = str.length - 1;
while (left < right) {
if (str[left] !== str[right]) {
return false;
}
left++;
right--;
}
return true;
}
// s是原始字符串 start: 当前处理的子串起始位置。path: 用于存储当前递归路径上的回文子串。result: 最终结果数组,用于收集所有满足条件的分割方案。
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);
}
// 测试用例
// const testString = "aab";
// const result = partitionPalindromes(testString);
// console.log(result);