@ 代码随想录算法训练营第5周(C语言)|Day27(回溯)
Day27、回溯(包含题目 39. 组合总和 40.组合总和II131.分割回文串)
39. 组合总和
题目描述
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
题目解答
int **res;
int reslen;
int *path;
int pathlen;
int count;
int *countnums;
void bfs(int *candidates,int candidatesSize,int target,int sum,int index){
if(sum>target){
return;
}
if(sum==target){
int*temp=(int*)malloc(sizeof(int)*pathlen);
for(int i=0;i<pathlen;i++){
temp[i]=path[i];
}
res[reslen]=temp;
countnums[reslen++]=pathlen;
return;
}
for(int i=index;i<candidatesSize;i++){
sum+=candidates[i];
path[pathlen++]=candidates[i];
bfs(candidates,candidatesSize,target,sum,i);
sum-=candidates[i];
pathlen--;
}
}
int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
res=(int**)malloc(sizeof(int*)*10000);
path=(int*)malloc(sizeof(int)*50);
countnums=(int*)malloc(sizeof(int)*10000);
reslen=pathlen=0;
bfs(candidates,candidatesSize,target,0,0);
*returnSize=reslen;
*returnColumnSizes=(int*)malloc(sizeof(int)*reslen);
for(int i=0;i<reslen;i++){
(*returnColumnSizes)[i]=countnums[i];
}
return res;
}
题目总结
组合。
40.组合总和II
题目描述
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
题目解答
int **res;
int reslen;
int *path;
int pathlen;
int *countnum;
int cmp(const void* a1, const void* a2) {
return *((int*)a1) - *((int*)a2);
}
void bfs(int* candidates,int candidatesSize,int target,int sum,int startindex){
if(sum>=target){
if(sum==target){
int*temp=(int*)malloc(sizeof(int)*pathlen);
for(int i=0;i<pathlen;i++){
temp[i]=path[i];
}
countnum[reslen]=pathlen;
res[reslen++]=temp;
}
return;
}
for(int i=startindex;i<candidatesSize;i++){
if(i>startindex&&candidates[i]==candidates[i-1]){
continue;
}
path[pathlen++]=candidates[i];
sum+=candidates[i];
bfs(candidates,candidatesSize,target,sum,i+1);
pathlen--;
sum-=candidates[i];
}
}
// void qsortcand(int *candidates,int left,int right){
// if(left>=right){
// return;
// }
// int cur=candidates[left];
// int left1=left;
// int right1=right;
// while(left1<right1){
// while(left1<right1&&candidates[right1]>=cur){
// right1--;
// }
// candidates[left1]=candidates[right1];
// while(left1<right1&&candidates[left1]<=cur){
// left1++;
// }
// candidates[right1]=candidates[left1];
// }
// candidates[left1]=cur;
// qsortcand(candidates,left,left1-1);
// qsortcand(candidates,left1+1,right);
// }
int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
res=(int**)malloc(sizeof(int*)*1000);
path=(int*)malloc(sizeof(int)*50);
countnum=(int*)malloc(sizeof(int)*1000);
reslen=pathlen=0;
// qsortcand(candidates,0,candidatesSize-1);
qsort(candidates, candidatesSize, sizeof(int), cmp);
bfs(candidates,candidatesSize,target,0,0);
*returnSize=reslen;
(*returnColumnSizes)=(int*)malloc(sizeof(int)*reslen);
for(int i=0;i<reslen;i++){
(*returnColumnSizes)[i]=countnum[i];
}
return res;
}
题目总结
这是树的宽度去重+快排。
131.分割回文串
题目描述
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例: 输入: “aab” 输出: [ [“aa”,“b”], [“a”,“a”,“b”] ]
题目解答
char**path;
int pathlen;
char***res;
int reslen;
int* ressize;
void copy(){
char**temp=(char**)malloc(sizeof(char*)*pathlen);
for(int i=0;i<pathlen;i++){
temp[i]=path[i];
}
res[reslen]=temp;
ressize[reslen++]=pathlen;
}
bool ispalindrome(char*str,int startindex,int endindex){
while(endindex>=startindex){
if(str[endindex--]!=str[startindex++]){
return 0;
}
}
return 1;
}
char*cutstring(char*str,int startindex,int endindex){
char*temp=(char*)malloc(sizeof(char)*(endindex-startindex+2));
int index=0;
for(int i=startindex;i<=endindex;i++){
temp[index++]=str[i];
}
temp[index]='\0';
return temp;
}
void bfs(char*str,int strlen,int startindex){
if(startindex>=strlen){
copy();
return;
}
for(int i=startindex;i<strlen;i++){
if(ispalindrome(str,startindex,i)){
path[pathlen++]=cutstring(str,startindex,i);
}else{
continue;
}
bfs(str,strlen,i+1);
pathlen--;
}
}
char*** partition(char* s, int* returnSize, int** returnColumnSizes) {
int strlen1=strlen(s);
path=(char**)malloc(sizeof(char*)*strlen1);
res=(char***)malloc(sizeof(char**)*40000);
ressize=(int*)malloc(sizeof(int)*40000);
reslen=pathlen=0;
bfs(s,strlen1,0);
*returnSize=reslen;
*returnColumnSizes=(int*)malloc(sizeof(int)*reslen);
for(int i=0;i<reslen;i++){
(*returnColumnSizes)[i]=ressize[i];
}
return res;
}
题目总结
回文子串。