- 分割回文串
给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。回文串 是正着读和反着读都一样的字符串。
示例 1:
输入:s = “aab”
输出:[[“a”,“a”,“b”],[“aa”,“b”]] 示例 2:输入:s = “a”
输出:[[“a”]]提示:
1 <= s.length <= 16 s 仅由小写英文字母组成 通过次数96,254提交次数132,313 在真实的面试中遇到过这道题?
/**
* Return an array of arrays of size *returnSize.
* The sizes of the arrays are returned as *returnColumnSizes array.
* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
*/
//先来一个双指针法判断是否为回文串
bool IsHuiWen(char * a,int left, int right)
{
while(left<right)
{
if(a[left]!=a[right])
{
return false;
}
left++;
right--;
}
return true;
}
//注意参数 很容易写错 buffer和index是缓冲区
//res和returnXXX是和返回最终结果相关
//s是源字符串 他们每一个都会在回溯中改变
void dfs(char* s,int len,char ***res,int** returnColumnSizes,int * returnSize,char buffer[][len +1],int index)
{
int i;
if(*s=='\0')//要结束了,说明是一个合法的结果
//要把缓冲去的二维数组放到目标三维结果中去
{
res[*returnSize] =(char**)malloc(sizeof(char*)*len);
for( i =0;i<index;i++)
{
res[*returnSize][i]=(char *)malloc(sizeof(char)*(len+1));
strcpy(res[*returnSize][i], buffer[i]);
}
(*returnColumnSizes)[(*returnSize)++] = index;
return;
}
int len2 = strlen(s);
for (i = 0; i < len2; i++) {
if (IsHuiWen(s, 0, i)) {
strncpy(buffer[index], s, i + 1);
buffer[index][i + 1] = '\0';
dfs(s + i + 1, len, res, returnColumnSizes,returnSize, buffer, index + 1);
}
}
}
char *** partition(char * s, int* returnSize, int** returnColumnSizes){
//第一想法就是使用递归回溯法
//判断结束的标志就是看是否为回文串
//所以要有一个函数用来这个字串是否为回文串
//c语言写这样的题就是太麻烦了
if (strlen(s) == 0) {
*returnSize = 0;
return NULL;
}
int len = strlen(s);
char ***res = (char***)malloc(sizeof(char**) * 32768);
char buffer[len][len + 1]; /* 临时buffer*/
*returnSize = 0;
*returnColumnSizes = (int*)malloc(sizeof(int) * 32768);
//32678 是指如果是最大长度16时 其最多可产生的结果
dfs(s, len, res, returnColumnSizes,returnSize, buffer, 0);
return res;
}
- 总结一 、经典的回溯剪枝法 特别时dfs中的写法,得到结果怎么办 ,何时剪枝,什么时候进行下次的分支,以及本次分支如何保存结果,回溯时如何让结果也回溯
- 总结二、这道题中的32768是边界值要注意到,buffer数组缓冲数组在dfs中传递的方式
- 总结三、这道题中的指针使用特别流畅
- 总结四、strcpy 和strncpy的区别