@ 代码随想录算法训练营第5周(C语言)|Day27(回溯)

@ 代码随想录算法训练营第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
//         while(left1=cur){
//             right1--;
//         }
//         candidates[left1]=candidates[right1];
//         while(left1
//             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;
}

题目总结

回文子串。

你可能感兴趣的:(算法,c语言,数据结构)