【代码随想录】【算法训练营】【第27天】 [39]组合总和 [40] 组合总和II [131]分割回文串

前言

思路及算法思维,指路 代码随想录。
题目来自 LeetCode。

day26, 休息的周末~
day 27,周一,库存没了,哭死~

题目详情

[39] 组合总和

题目描述

39 组合总和
39 组合总和

解题思路

前提:组合的子集问题,统一元素可以重复选取
思路:回溯 + 剪枝。
重点:剪枝的前提是数组已排序。

代码实现

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 backtracing(int* candidates, int candidatesSize, int target, int index, int *nums, int numsSize, int ***ans, int* returnSize, int** returnColumnSizes)
{
    // 退出条件
    if (0 == target)
    {
        *ans = (int **)realloc(*ans, sizeof(int *) * ((*returnSize) + 1));
        (*ans)[*returnSize] = (int *)malloc(sizeof(int) * (numsSize));
        for (int i = 0; i < numsSize; i++)
        {
            (*ans)[*returnSize][i] = nums[i];
        }
        *returnColumnSizes = (int *)realloc(*returnColumnSizes, sizeof(int) * ((*returnSize) + 1));
        (*returnColumnSizes)[*returnSize] = numsSize;
        (*returnSize)++;
        return ;
    }
    
    for (int j = index; j < candidatesSize; j++)
    {
        if (target < candidates[j])
        {
            continue ;
        }
        // 递归
        nums[numsSize] = candidates[j];
        numsSize++;
        backtracing(candidates, candidatesSize, target - candidates[j], j, nums, numsSize, ans, returnSize, returnColumnSizes);
        // 回溯
        numsSize--;
        nums[numsSize] = 0;
    }
    return ;
}

int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
    // 判空
    if (candidatesSize == 0)
    {
        return NULL;
    }
    // 输出
    int **ans = NULL;
    int nums[41];
    int index = 0;
    *returnSize = 0;
    printf("%d\n", target);
    backtracing(candidates, candidatesSize, target, 0, nums, 0, &ans, returnSize, returnColumnSizes);
    if (*returnSize == 0)
    {
        return NULL;
    }
    return ans;
}
回溯 + 排序 + 剪枝
/**
 * 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().
 */

int cmp(const void *p1, const void *p2)
{
    return *(int *)p1 > *(int *)p2;
}

void backtracing(int* candidates, int candidatesSize, int target, int index, int *nums, int numsSize, int ***ans, int* returnSize, int** returnColumnSizes)
{
    // 退出条件
    if (0 == target)
    {
        *ans = (int **)realloc(*ans, sizeof(int *) * ((*returnSize) + 1));
        (*ans)[*returnSize] = (int *)malloc(sizeof(int) * (numsSize));
        for (int i = 0; i < numsSize; i++)
        {
            (*ans)[*returnSize][i] = nums[i];
        }
        *returnColumnSizes = (int *)realloc(*returnColumnSizes, sizeof(int) * ((*returnSize) + 1));
        (*returnColumnSizes)[*returnSize] = numsSize;
        (*returnSize)++;
        return ;
    }
    
    // 剪枝
    for (int j = index; (j < candidatesSize) && (target >= candidates[j]); j++)
    {
        // 递归
        nums[numsSize] = candidates[j];
        numsSize++;
        backtracing(candidates, candidatesSize, target - candidates[j], j, nums, numsSize, ans, returnSize, returnColumnSizes);
        // 回溯
        numsSize--;
        nums[numsSize] = 0;
    }
    return ;
}

int** combinationSum(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
    // 判空
    if (candidatesSize == 0)
    {
        return NULL;
    }
    // 排序
    qsort(candidates, candidatesSize, sizeof(int), cmp);
    // 输出
    int **ans = NULL;
    int nums[41];
    int index = 0;
    *returnSize = 0;
    backtracing(candidates, candidatesSize, target, 0, nums, 0, &ans, returnSize, returnColumnSizes);
    if (*returnSize == 0)
    {
        return NULL;
    }
    return ans;
}

[40] 组合总和II

题目描述

40 组合总和II
40 组合总和II

解题思路

前提:组合的子集问题,同一元素只能使用一次,但是结果不包含重复组合
思路:回溯 + 剪枝
重点:结果子集中排除重复组合,需要树形结构中,同一树层的相同的元素值不可重复选取,使用used数组实现去重。

代码实现

C语言
利用used数组 false,同一树层 去重
/**
 * 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().
 */

int cmp(const void *p1, const void *p2)
{
    return *(int *)p1 > *(int *)p2;
}

void backtracing(int* candidates, int candidatesSize, int target, int index, int *nums, int numsSize, bool *used, int ***ans, int* returnSize, int** returnColumnSizes)
{
    // 退出条件
    if (0 == target)
    {
        *ans = (int **)realloc(*ans, sizeof(int *) * ((*returnSize) + 1));
        (*ans)[*returnSize] = (int *)malloc(sizeof(int) * (numsSize));
        for (int i = 0; i < numsSize; i++)
        {
            (*ans)[*returnSize][i] = nums[i];
        }
        *returnColumnSizes = (int *)realloc(*returnColumnSizes, sizeof(int) * ((*returnSize) + 1));
        (*returnColumnSizes)[*returnSize] = numsSize;
        (*returnSize)++;
        return ;
    }
    for (int j = index; (j < candidatesSize) && (target >= candidates[j]); j++)
    {
        // 去重
        if ((j > 0) && (candidates[j] == candidates[j - 1]) && (used[j - 1] == false))
        {
            continue;
        }
        // 递归
        nums[numsSize] = candidates[j];
        used[j] = true;
        numsSize++;
        backtracing(candidates, candidatesSize, target - candidates[j], j + 1, nums, numsSize, used, ans, returnSize, returnColumnSizes);
        // 回溯
        numsSize--;
        used[j] = false;
        nums[numsSize] = 0;
    }
    return ;
}

int** combinationSum2(int* candidates, int candidatesSize, int target, int* returnSize, int** returnColumnSizes) {
    // 判空
    if (candidatesSize == 0)
    {
        return NULL;
    }
    // 排序
    qsort(candidates, candidatesSize, sizeof(int), cmp);
    // 输出
    int **ans = NULL;
    int nums[100] = {0};
    bool used[100] = {false};
    int index = 0;
    *returnSize = 0;
    backtracing(candidates, candidatesSize, target, 0, nums, 0, used, &ans, returnSize, returnColumnSizes);
    if (*returnSize == 0)
    {
        return NULL;
    }
    return ans;
}

[131] 分割回文串

题目描述

131 分割回文串
131 分割回文串

解题思路

前提:分割问题
思路:。
重点:。

代码实现

C语言
// 待补充

今日收获

  1. 组合子集问题:去重,同一树层去重 vs 同一树杈去重
  2. 切割问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/676174.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上位机图像处理和嵌入式模块部署(f103 mcu获取唯一id)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于stm32f103系列mcu来说&#xff0c;一般每一颗原厂的mcu&#xff0c;都会对应一个唯一的id。那这个id可以用来做什么用呢&#xff1f;个人认为&…

【电子通识】什么是电力电子

什么是电力电子 在日常生活中&#xff0c;电能变换的需求无处不在。比如给手机充电&#xff0c;充电器从插座220V交流电取电并转换为手机电池所需的5V或者其他幅度的直流电输送给手机&#xff0c;这就完成了最简单的AC-DC电能转换。除此之外&#xff0c;还有空调、电视、新能源…

LLM主流开源代表模型

LLM主流开源大模型介绍 1 LLM主流大模型类别 随着ChatGPT迅速火爆&#xff0c;引发了大模型的时代变革&#xff0c;国内外各大公司也快速跟进生成式AI市场&#xff0c;近百款大模型发布及应用。 目前&#xff0c;市面上已经开源了各种类型的大语言模型&#xff0c;本章节我们…

【数据结构】详解堆的基本结构及其实现

文章目录 前言1.堆的相关概念1.1堆的概念1.2堆的分类1.2.1小根堆1.2.2大根堆 1.3堆的特点堆的实用场景 2.堆的实现2.1初始化2.2插入2.3堆的向上调整2.4删除2.5堆的向下调整2.6判空2.7获取堆顶元素2.8销毁 3.堆排序3.1实现3.2堆排序的时间复杂度问题 前言 在上一篇文章中&#…

大模型时代的具身智能系列专题(七)

北大王鹤团队 王鹤&#xff0c;北京大学前沿计算研究中心助理教授&#xff0c;本科毕业于清华大学&#xff0c;博士毕业于斯坦福大学&#xff0c;师从美国三院院士Leonidas. J Guibas教授。他创立并领导了具身感知与交互实验室(EPIC Lab)&#xff0c;实验室立足三维视觉感知与…

怎么控制员工电脑的文件外发,六个控制文件外发的小窍门你必须了解

控制员工电脑的文件外发是企业信息安全管理中的重要环节&#xff0c;旨在防止敏感数据泄露、保护知识产权和维护商业秘密。 企业可以通过多种技术和管理措施相结合的方式来达到这一目的&#xff0c;确保既有效控制文件外发风险&#xff0c;又不影响正常的业务运作和员工工作效…

Java设计模式——建造者模式

目录 前言 一、什么是建造者模式 二、建造者模式的核心角色 三、建造者模式的优点 四、具体实现 1、抽象建造者类 2、具体建造者类 3、产品类 4、指挥者类 5、客户端代码 总结 前言 在软件工程中&#xff0c;我们经常遇到需要创建复杂对象的情况。这些对象可能由多个…

MongoDB CRUD操作:地理位置查询中的GeoJSON对象

MongoDB CRUD操作&#xff1a;地理位置查询中的GeoJSON对象 文章目录 MongoDB CRUD操作&#xff1a;地理位置查询中的GeoJSON对象Point类型LineString类型Polygon&#xff08;多边形&#xff09;类型单环多边形多环多边形 MultiPoint类型MultiLineString类型MultiPolygon类型Ge…

[FreeRTOS 基础知识] 堆

文章目录 堆的概念使用C语言实现 堆堆空间解析 堆的概念 所谓的堆就是一块空间的内存&#xff0c;可以来管理这块内存。从这块内存中取出一部分然后再释放回去。 使用C语言实现 堆 char heap_buf[1024]; // 定义一个堆空间 int pos0; // 当前…

牛客网刷题 | BC116 [NOIP2013]记数问题

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 试计算在区间1 到n…

C++的vector使用优化

我们在上一章说了如何使用这个vector动态数组&#xff0c;这章我们说说如何更好的使用它以及它是如何工作的。当你创建一个vector&#xff0c;然后使用push_back添加元素&#xff0c;当当前的vector的内存不够时&#xff0c;会从内存中的旧位置复制到内存中的新位置&#xff0c…

pytorch+YOLOv8-1

1.工具开发 2.idea配置pytorch环境 默认安装新版本torch pip install torch 3.pytorch验证 4. print(torch.cuda.is_available()) 输出结果为 False 说明我只能用cpu

【动手学深度学习】softmax回归的简洁实现详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 softmax回归的简洁实现 &#x1f30d;3.2 基础练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 理解softmax回归的原理和基本实现方式&#xff1b;学习如何…

prometheus+alertmanager+webhook钉钉机器人告警

版本&#xff1a;centos7.9 python3.9.5 alertmanager0.25.0 prometheus2.46.0 安装alertmanager prometheus 配置webhook # 解压&#xff1a; tar -xvf alertmanager-0.25.0.linux-amd64.tar.gz tar -xvf prometheus-2.46.0.linux-amd64.tar.gz mv alertmanager-0.25.0.linu…

分享毕业论文要怎么写以及写论文工具推荐

毕业论文的写作是一个系统且需要深度研究的过程。以下将分步介绍毕业论文的写作方法&#xff0c;并推荐一些实用的写作工具。 毕业论文写作方法 选题&#xff1a; 确定研究方向和目标&#xff0c;选择具体且有一定研究价值的课题。建议选择应用型题目&#xff0c;结合理论和实…

【HarmonyOS】鸿蒙系统中应用权限等级介绍、定义、申请授权讲解

【HarmonyOS】鸿蒙系统中应用权限等级介绍、定义、申请授权讲解 针对权限等级&#xff0c;相对于主体来说&#xff0c;会有不同的细分概念。 一、权限APL等级&#xff1a; 首先在鸿蒙系统中&#xff0c;对于权限本身&#xff0c;分为三个等级&#xff1a;normal&#xff0c;s…

【JAVA WEB实用与优化技巧】如何使用本地.bat/.sh脚本快速将服务发布到测试环境?

文章目录 普通方式的springboot 使用docker打包发布【手动构建镜像模式】1. maven 打包可运行jar包2.手动打包镜像3.运行容器 全自动化本地命令发布到远程服务的方式配置ssh信任公钥获取公钥git 获取公钥方式: 桌面右键 -> open git gui here -> help -> show SSH key…

【数据库】MySQL表的操作

目录 一.创建表 二.查看表 三.修改表 四.删除表 一.创建表 基本语法&#xff1a; CREATE TABLE table_name(field1 datatype,field2 datatype,field3 datatype) character set 字符集 collate 校验规则 engine 储存引擎field表示列名 datatype表示列的类型 charatcer se…

初识C++ · 模拟实现stack和Queue

目录 前言&#xff1a; 1 Stack 1.1 双端队列 2 Queue 前言&#xff1a; 经历了list三个自定义类型的洗礼&#xff0c;来个简单的放松放松&#xff0c;即栈和队列&#xff1a; 文档记录的&#xff0c;栈和队列是一种容器适配器&#xff0c;它们不属于stl&#xff0c;但是它…

什么是云渲染?怎么使用呢?手把手教你

云渲染是一种利用云计算技术进行图形渲染的服务。它允许用户将渲染任务提交到云端服务器&#xff0c;由远程的计算机集群资源进行渲染操作&#xff0c;完成后再将渲染结果返回给用户。 云渲染技术的优势在于它可以提高渲染效率和质量&#xff0c;支持多任务同时加速渲染&#…