39. 组合总和
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
- 所有数字(包括 target)都是正整数。
- 解集不能包含重复的组合。
示例 1:
- 输入:candidates = [2,3,6,7], target = 7,
- 所求解集为: [ [7], [2,2,3] ]
示例 2:
- 输入:candidates = [2,3,5], target = 8,
- 所求解集为: [ [2,2,2,2], [2,3,3], [3,5] ]
void bp(int **ans,int *returnSize,int *path,int *p,int *candidates,int candidatesSize,int target,int sum,int** returnColumnSizes,int start){
if(sum>target) return;
if(sum==target ) {
ans[*returnSize]=malloc(sizeof(int)*(*p));
for (int i=0;i<*p;i++){
ans[*returnSize][i]=path[i];
}
(*returnColumnSizes)[*returnSize]=(*p);
(*returnSize)++;
return;
}
for (int i=start;i<candidatesSize;i++){
path[(*p)++]=candidates[i];
bp(ans, returnSize, path, p, candidates, candidatesSize, target, sum+candidates[i],returnColumnSizes,i);
(*p)--;
}
}
int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
int **ans=(int **)malloc(sizeof(int *)*151);
*returnSize=0;
int *path=(int *)malloc(sizeof(int )*target);
int p=0;
*returnColumnSizes=(int *)malloc(sizeof(int )*151);
bp(ans,returnSize, path, &p, candidates,candidatesSize, target, 0,returnColumnSizes,0);
return ans;
}
40.组合总和II !!!
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明: 所有数字(包括目标数)都是正整数。解集不能包含重复的组合。
1、用快排——如果这个数字和上一个一样,则跳过这个数字——避免 122,221这种情况
2、for中continue的用法:跳过本轮
break:跳出break
int cmp(const void* a, const void* b){
return *(int*)a - *(int*)b;
}
void bp(int **ans,int *returnSize,int *path,int *p,int *candidates,int candidatesSize,int target,int sum,int** returnColumnSizes,int start){
if(sum>target) return;
if(sum==target ) {
ans[*returnSize]=malloc(sizeof(int)*(*p));
for (int i=0;i<*p;i++){
ans[*returnSize][i]=path[i];
}
(*returnColumnSizes)[*returnSize]=(*p);
(*returnSize)++;
return;
}
for (int i=start;i<candidatesSize;i++){
if(i>start && candidates[i]==candidates[i-1]) continue;
path[(*p)++]=candidates[i];
bp(ans, returnSize, path, p, candidates, candidatesSize, target, sum+candidates[i],returnColumnSizes,i+1);
(*p)--;
}
}
int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
qsort(candidates, candidatesSize, sizeof(int), cmp);
int **ans=(int **)malloc(sizeof(int *)*151);
*returnSize=0;
int *path=(int *)malloc(sizeof(int )*target);
int p=0;
*returnColumnSizes=(int *)malloc(sizeof(int )*151);
bp(ans,returnSize, path, &p, candidates,candidatesSize, target, 0,returnColumnSizes,0);
return ans;
}
131.分割回文串 !!!
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例: 输入: "aab" 输出: [ ["aa","b"], ["a","a","b"] ]
分析:
bp
1、if 全部切割完了——输出
2、for循环 讨论这次的切割位置——判断新切出来的这段,是否是回文——不是,则去下一个切割位置;是则输入path
注意:
1、回溯时,如果在bp函数的参数里 bp(x+1),这样修改参数,因为参数不会回传(*x不适用),所以可以省去后续的显式回溯——这就是为什么之前写递归的时候,不会把回溯的部分写出来
2、char**,int** 这类的每一层在使用前都需要进行malloc
3、对于自己写入字符串,需要留出0的位置
strlen不包含0的位置
bool reverse(char *s,int left,int right){///回文的判断
while(left<=right){
if(s[left]!=s[right]) return false;;
left++;
right--;
}
return true;
}
void bp(char*s,char ***ans,char **path,int *p,int left,int *returnSize,int*returnColumnSizes){
if(left>=strlen(s)){/
ans[*returnSize]=(char**)malloc(sizeof(char*)*(*p));
for(int i=0;i<*p;i++){
ans[*returnSize][i]=(char*)malloc(sizeof(char)*(strlen(s)+1));///每层都要开辟空间
strcpy(ans[(*returnSize)][i],path[i]);///类似于切片操作
}
returnColumnSizes[*returnSize]=*p;
(*returnSize)++;
return;
}
for (int i=left;i<strlen(s);i++){//right从0开始
if (!reverse(s, left, i)) continue;
strncpy( path[*p],s+left,i-left+1); /// 类似于切片的操作
path[(*p)++][i-left+1]='\0'; ///自己创造字符串的时候,需要加/0
bp(s, ans, path, p, i+1,returnSize,returnColumnSizes);
(*p)--;
}
}
char*** partition(char* s, int* returnSize, int** returnColumnSizes){
char *** ans = (char ***)malloc(sizeof(int **) * 50000);
*returnColumnSizes=(int *)malloc(sizeof(int)*50000);
char **path=(char**)malloc(sizeof(char*)* strlen(s));
for(int i=0;i<strlen(s);i++){
path[i]=(char*)malloc(sizeof(char)* (strlen(s)+1));//strlen不包括/0的长度,但是实际输出的时候需要加上0;每层都要开辟空间
}
int p=0;
*returnSize=0;
bp(s,ans, path, &p, 0, returnSize,*returnColumnSizes);
return ans;
}