思路:这题知道用回溯,但是不知道该怎么切割。比如:切割线如何模拟?如何截取切割后的子串?如何判断回文?我在b站上看了代码随想录的视频,然后才明白,明白后发现和前面的组合还是挺类似的。
依然是回溯三部曲:
- 递归函参:
char *s,int startIndex
.因为是在同一个集合中,需要用到startIndex。 - 终止条件:
startIndex >=strlen(s)
.观察树形结构图可以发现,切割线到了字符串的最后面,就是本轮递归的终止条件。startIndex是切割线。 - 单层搜索:
(int i=startIndex;i<strlen(s);i++)
,判断子串是否为回文子串,然后将切割后的子串存入path。
截取切割后的子串:起始位置为startIndex,那么(startIndex,i]就表示截取的子串了。
在写backTrack()前,我们先写出这三个函数。
copy():将path中的字符串全部复制到result中
isPalindrome():判断字符串是否为回文字符串
cutString():切割从startIndex到i的子字符串
char **path;
int pathTop;
char ***result;
int resultTop;
int *length;
void copy(){
char **temp = malloc(sizeof(char*)*pathTop);
for(int i=0;i<pathTop;i++)
temp[i] = path[i];
result[resultTop] = temp;
length[resultTop++] = pathTop;
}
bool isPalindrome(char *s,int startIndex , int endIndex){
while(endIndex >= startIndex) {
if(s[endIndex--] != s[startIndex++])
return false;
}
return true;
}
char *cutString(char *s,int startIndex,int endIndex){
char *temp2 = malloc(sizeof(char)*(endIndex - startIndex +2));
int index = 0;
for(int i=startIndex;i<=endIndex;i++)
temp2[index++] = s[i];
temp2[index] = '\0';
return temp2;
}
void backTrack(char *s,int startIndex){
if(startIndex >= strlen(s)){
copy();
return;
}
for(int i=startIndex;i<strlen(s);i++){
if(isPalindrome(s,startIndex,i)){
path[pathTop++] = cutString(s,startIndex,i);
}else{
continue;
}
backTrack(s,i+1);
pathTop--;
}
}
char*** partition(char* s, int* returnSize, int** returnColumnSizes){
path=malloc(sizeof(char*) *strlen(s));
result = malloc(sizeof(char**) *50000);
length= malloc(sizeof(int) *50000);
pathTop = resultTop = 0;
backTrack(s,0);
*returnSize = resultTop;
*returnColumnSizes=malloc(sizeof(int)*resultTop);
for(int i=0;i<resultTop;i++)
(*returnColumnSizes)[i] = length[i];
return result;
}