int* path;
int pathSize;
int** ans;
int ansTop;
void backtracking(int n,int k,int startIndex){
//当path中元素个数为k个时,我们需要将path数组放入ans二维数组中
if(pathSize==k){
//path数组为我们动态申请,若直接将其地址放入二维数组,path数组中的值会随着我们回溯而逐渐变化
//因此创建新的数组存储path中的值
int* temp=(int*)malloc(sizeof(int)*k);
int i;
for(i=0;i<k;i++){
temp[i]=path[i];
}
ans[ansTop++]=temp;
return;
}
int j;
for(j=startIndex;j<=n;j++){
//将当前结点放入path数组
path[pathSize++]=j;
//进行递归
backtracking(n,k,j+1);
//进行回溯,将数组最上层结点弹出
pathSize--;
}
}
// 让我们通过一个更详细的例子来解释这段代码的工作原理,以从数字1到5中选择3个数字的所有组合为例(n=5, k=3)。
// 初始化
// 假设pathSize = 0, ansTop = 0, startIndex = 1。
// path和ans已预先分配足够的内存。
// 第一次递归调用
// 入口检查: pathSize != k,开始循环。
// 尝试第一个元素 (j=1):
// path[pathSize++] = j; => path现在包含[1], pathSize=1。
// 递归调用backtracking(5, 3, 2)。
// 第二次递归调用
// 入口检查: pathSize != k,继续循环。
// 尝试第二个元素 (j=2):
// path[pathSize++] = j; => path现在包含[1, 2], pathSize=2。
// 递归调用backtracking(5, 3, 3)。
// 第三次递归调用(找到一个组合)
// 入口检查: pathSize == k(此时pathSize=2, 但此处应修正为判断失误,
// 正确的逻辑应在pathSize达到3时停止循环并处理组合),此处描述按照逻辑修正。
// 尝试第三个元素 (j=3):
// path[pathSize++] = j; => path现在包含[1, 2, 3], pathSize=3。
// 找到组合: pathSize == k,创建临时数组temp,复制path到temp,然后ans[ansTop++] = temp;
// ,此时ansTop=1,表示收集到了第一个组合。
// 递归调用结束,开始回溯,pathSize--; => pathSize=2,移除path中的最后一个元素(3)。
// 回溯至第二次递归调用
// 接着尝试j=4:
// path[pathSize++] = 4; => path现在包含[1, 2, 4], pathSize=3。
// 发现组合,同上处理,收集组合,回溯,pathSize--; => pathSize=2,移除4。
// 继续回溯至第一次递归调用
// 探索j=5:
// path[pathSize++] = 5; => path现在包含[1, 2, 5], pathSize=3。
// 收集组合,回溯,pathSize--; => pathSize=2,移除5。
// 回到第一次循环的后续步骤
// 接下来,由于j已经在第一次循环中递增到5,循环结束,开始回溯,pathSize--; => pathSize=1,移除2。
// 第一轮循环结束
// 继续探索以j=2开始的新一轮,类似过程,会找到包含[1, 3, 4]、[1, 3, 5]、[1, 4, 5]等所有可能的组合,
// 每次完成一个组合的探索后都会进行回溯,为下一次探索做准备。
int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {
//path数组存储符合条件的结果
path=(int*)malloc(sizeof(int)*k);
//ans二维数组存储符合条件的结果数组的集合。(数组足够大,避免极端情况)
ans=(int**)malloc(sizeof(int*)*10000);
pathSize=ansTop=0;
backtracking(n,k,1);
//最后的返回大小为ans数组大小
*returnSize=ansTop;
//returnColumnSizes数组存储ans二维数组对应下标中一维数组的长度(都为k)
*returnColumnSizes=(int*)malloc(sizeof(int)*(*returnSize));
int i;
for(i=0;i<*returnSize;i++){
(*returnColumnSizes)[i]=k;
}
//返回ans二维数组
return ans;
}