一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情
题目(Palindrome Partitioning)
链接:https://leetcode-cn.com/problems/palindrome-partitioning
解决数:1150
通过率:72.7%
标签:字符串 动态规划 回溯
相关公司:amazon bytedance google
给你一个字符串 s,请你将 **s **分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。
回文串 是正着读和反着读都一样的字符串。
示例 1:
输入: s = "aab"
输出: [["a","a","b"],["aa","b"]]
示例 2:
输入: s = "a"
输出: [["a"]]
提示:
1 <= s.length <= 16s仅由小写英文字母组成
思路
先对示例"aab"进行分割。
- 我们需要一个变量
start去表示分割的s(在上图中start从0,1,2开始,分别将s="aab"分割为第二行的ab, b, 空)。 - 需要一个数组
temp去保存取走的字符(在上图分别是a,aa,aab)。 - 此时进行第二行分割。ab,b,空为s,回到第一步。
- 当为空(
start不能继续加一去分割s了,start === s.length)就保存temp; - 将
temp数组最后的字符释放(回溯)。 然后就可以根据公式编写基础版本的代码,得到字符的全部顺序组合:
var partition = function (s) {
//res保存最终结果,temp表示每一个路径分支产生的结果
var res = [], temp = [];
var start = 0; //start表示从s的哪一位开始,这里从s的第0位开始
// 递归函数
partitionStr(s, start, temp, res);
return res;
};
function partitionStr(s, start, temp, res) {
if (start === s.length) { //递归终止条件
res.push([...temp]);//不能直接将temp数组push,那样push的是temp的引用
return;
}
for (var i = start; i < s.length; i++) {
//rest是s的前i个字符(也就是取走的字符,在aab图中是第一行的a,aa,aab等)
var rest = s.substring(start, i + 1);
temp.push(rest);
//保存了前i个字符(rest)就继续从第i+1开始分割
partitionStr(s, i + 1, temp, res);
temp.pop();
}
}
然后考虑题目是需要保证每一个顺序组合是回文串,所以增加一个判断——是回文串才会将restpush进temp数组,不是就不继续递归这条路径。
var partition = function (s) {
var res = [];
partitionStr(s, 0, [], res);
return res;
};
function partitionStr(s, start, temp, res) {
if (start === s.length) {
res.push([...temp]);
return;
}
for (var i = start; i < s.length; i++) {
//判断当前的rest是否是回文串
if (isPalindrome(s, start, i)) {
temp.push(s.substring(start, i + 1));
partitionStr(s, i + 1, temp, res);
temp.pop();
} else {
continue;
}
}
}
var isPalindrome = function (s, l, r) {
while (l <= r) {
if (s[l] !== s[r]) return false;
l++;
r--;
}
return true;
};