【代码随想录】【算法训练营】【第24天】 [77]组合

前言

思路及算法思维,指路 代码随想录

题目来自 LeetCode

day 23,愉快的周五~

题目详情

[77] 组合

题目描述

77 组合

解题思路

前提:组合求子集问题

思路:回溯算法三部曲:递归函数的返回值以及参数、回溯函数终止条件、单层搜索的过程。

重点:回溯算法是一种暴力求解,常常会超出时间限制,需要剪枝操作。

txt 复制代码
回溯法,一般可以解决如下几种问题:
组合问题:N个数里面按一定规则找出k个数的集合
切割问题:一个字符串按一定规则有几种切割方式
子集问题:一个N个数的集合里有多少符合条件的子集
排列问题:N个数按一定规则全排列,有几种排列方式
棋盘问题:N皇后,解数独等等

代码实现

C语言
未剪枝的回溯
c 复制代码
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

void backtracking(int n, int k, int startIndex, int *nums, int *numsSize, int **ans, int *returnSize, int **returnColumnSizes)
{
    if (*numsSize == k)
    {
        // 找到一个组合
        (*returnColumnSizes)[(*returnSize)] = k;
        ans[(*returnSize)] = (int *)malloc(sizeof(int) * k);
        for (int i = 0; i < k; i++)
        {
            ans[(*returnSize)][i] = nums[i];
        } 
        (*returnSize)++;
        return ;
    }
    // 未剪枝
    for (startIndex; startIndex <= n; startIndex++)
    {
        nums[(*numsSize)] = startIndex;
        (*numsSize)++;
        // 递归
        backtracking(n, k, startIndex + 1, nums, numsSize, ans, returnSize, returnColumnSizes);
        // 回溯
        (*numsSize)--;
        nums[(*numsSize)] = 0;
    }
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {
    int **ans = (int **)malloc(sizeof(int *) * 200000);
    *returnSize = 0;
    *returnColumnSizes = (int *)malloc(sizeof(int) * 200000);
    int nums[n];
    int numsSize = 0;
    backtracking(n, k, 1, nums, &numsSize, ans, returnSize, returnColumnSizes);
    return ans;
}

使用realloc会出现"内存超出限制"报错,原因未知~

剪枝的回溯
c 复制代码
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */

void backtracking(int n, int k, int startIndex, int *nums, int *numsSize, int **ans, int *returnSize, int **returnColumnSizes)
{
    if (*numsSize == k)
    {
        // 找到一个组合
        (*returnColumnSizes)[(*returnSize)] = k;
        ans[(*returnSize)] = (int *)malloc(sizeof(int) * k);
        for (int i = 0; i < k; i++)
        {
            ans[(*returnSize)][i] = nums[i];
        } 
        (*returnSize)++;
        return ;
    }
    // 剪枝
    for (startIndex; startIndex <= (n - (k - (*numsSize)) + 1); startIndex++)
    {
        nums[(*numsSize)] = startIndex;
        (*numsSize)++;
        // 递归
        backtracking(n, k, startIndex + 1, nums, numsSize, ans, returnSize, returnColumnSizes);
        // 回溯
        (*numsSize)--;
        nums[(*numsSize)] = 0;
    }
}

int** combine(int n, int k, int* returnSize, int** returnColumnSizes) {
    int **ans = (int **)malloc(sizeof(int *) * 200000);
    *returnSize = 0;
    *returnColumnSizes = (int *)malloc(sizeof(int) * 200000);
    int nums[n];
    int numsSize = 0;
    backtracking(n, k, 1, nums, &numsSize, ans, returnSize, returnColumnSizes);
    return ans;
}

今日收获

  1. 回溯算法三部曲:递归函数的返回值以及参数、回溯函数终止条件、单层搜索的过程;
  2. 剪枝操作。
相关推荐
夏鹏今天学习了吗7 小时前
【LeetCode热题100(82/100)】单词拆分
算法·leetcode·职场和发展
mit6.8248 小时前
mysql exe
算法
2501_901147838 小时前
动态规划在整除子集问题中的应用与高性能实现分析
算法·职场和发展·动态规划
中草药z8 小时前
【嵌入模型】概念、应用与两大 AI 开源社区(Hugging Face / 魔塔)
人工智能·算法·机器学习·数据集·向量·嵌入模型
知乎的哥廷根数学学派9 小时前
基于数据驱动的自适应正交小波基优化算法(Python)
开发语言·网络·人工智能·pytorch·python·深度学习·算法
ADI_OP9 小时前
ADAU1452的开发教程10:逻辑算法模块
算法·adi dsp中文资料·adi dsp·adi音频dsp·adi dsp开发教程·sigmadsp的开发详解
xingzhemengyou19 小时前
C语言 查找一个字符在字符串中第i次出现的位置
c语言·算法
小六子成长记11 小时前
【C++】:搜索二叉树的模拟实现
数据结构·c++·算法
汉克老师11 小时前
GESP2025年9月认证C++二级真题与解析(编程题1(优美的数字))
c++·算法·整除·枚举算法·求余·拆数
Zevalin爱灰灰12 小时前
现代控制理论——第二章 系统状态空间表达式的解
线性代数·算法·现代控制