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

news2024/11/26 10:17:38

前言

思路及算法思维,指路 代码随想录。
题目来自 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语言
/**
 * 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().
 */

char** path;
int pathTop;
char*** ans;
int ansTop = 0;
int* ansSize;

//将path中的字符串全部复制到ans中
void copy() {
    //创建一个临时tempPath保存path中的字符串
    char** tempPath = (char**)malloc(sizeof(char*) * pathTop);
    int i;
    for(i = 0; i < pathTop; i++) {
        tempPath[i] = path[i];
    }
    //保存tempPath
    ans[ansTop] = tempPath;
    //将当前path的长度(pathTop)保存在ansSize中
    ansSize[ansTop++] = pathTop;
}

//判断字符串是否为回文字符串
bool isPalindrome(char* str, int startIndex, int endIndex) {
    //双指针法:当endIndex(右指针)的值比startIndex(左指针)大时进行遍历
    while(endIndex >= startIndex) {
        //若左指针和右指针指向元素不一样,返回False
        if(str[endIndex--] != str[startIndex++])
            return false;
    }
    return true;
}

//切割从startIndex到endIndex子字符串
char* cutString(char* str, int startIndex, int endIndex) {
    //开辟字符串的空间
    char* tempString = (char*)malloc(sizeof(char) * (endIndex - startIndex + 2));
    int i;
    int index = 0;
    //复制子字符串
    for(i = startIndex; i <= endIndex; i++)
        tempString[index++] = str[i];
    //用'\0'作为字符串结尾
    tempString[index] = '\0';
    return tempString;
}

void backTracking(char* str, int strLen,  int startIndex) {
    if(startIndex >= strLen) {
        //将path拷贝到ans中
        copy();
        return ;
    }

    int i;
    for(i = startIndex; i < strLen; i++) {
        //若从subString到i的子串是回文字符串,将其放入path中
        if(isPalindrome(str, startIndex, i)) {
            path[pathTop++] = cutString(str, startIndex, i);
        }
        //若从startIndex到i的子串不为回文字符串,跳过这一层 
        else {
            continue;
        }
        //递归判断下一层
        backTracking(str, strLen, i + 1);
        //回溯,将path中最后一位元素弹出
        pathTop--;
    }
}

char*** partition(char* s, int* returnSize, int** returnColumnSizes){
    int strLen = strlen(s);
    //因为path中的字符串最多为strLen个(即单个字符的回文字符串),所以开辟strLen个char*空间
    path = (char**)malloc(sizeof(char*) * strLen);
    //存放path中的数组结果
    ans = (char***)malloc(sizeof(char**) * 40000);
    //存放ans数组中每一个char**数组的长度
    ansSize = (int*)malloc(sizeof(int) * 40000);
    ansTop = pathTop = 0;

    //回溯函数
    backTracking(s, strLen, 0);

    //将ansTop设置为ans数组的长度
    *returnSize = ansTop;
    //设置ans数组中每一个数组的长度
    *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
    int i;
    for(i = 0; i < ansTop; ++i) {
        (*returnColumnSizes)[i] = ansSize[i];
    }
    return ans;
}

今日收获

  1. 组合子集问题:去重,同一树层去重 vs 同一树杈去重
  2. 切割问题(好难,写不出来一点)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[matlab]折线图之多条折线如何绘制实心圆作为标记点

使用MarkerFaceColor是标记点填充的颜色&#xff0c;b&#xff0c;表示blue&#xff0c;蓝色 plot(x, a, d--, MarkerFaceColor, b); % 绘制仿真结果的曲线如果一张图多条曲线那么每条曲线需要单独调用一次plot&#xff0c;每个plot间用hold on 连接 plot(x, a, d--, MarkerF…

基于pytorch的车牌识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、导入数据 from torchvision.transforms import transforms from torch.utils.data import DataLoader from torchvision import datase…

VMware ESXi 8.0U2c macOS Unlocker OEM BIOS 集成网卡驱动 Marvell AQC 网卡定制版

VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS 集成网卡驱动 Marvell AQC 网卡定制版 VMware ESXi 8.0U2c macOS Unlocker & OEM BIOS 集成网卡驱动和 NVMe 驱动 (集成驱动版) 发布 ESXi 8.0U2 集成驱动版&#xff0c;在个人电脑上运行企业级工作负载 请访问原文链…

Python Virtualenv:创建独立的 Python 开发环境

在当今软件开发的世界中&#xff0c;Python 是一种备受欢迎的编程语言&#xff0c;其简洁、易读和强大的特性吸引了无数开发者。然而&#xff0c;随着项目的增多和复杂度的提高&#xff0c;有效地管理 Python 项目所需的各种依赖项和库变得越来越重要。在这种情况下&#xff0c…

【机器学习】医疗AI的突破:深度学习在医学影像诊断中的惊人表现

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、深度学习在医学影像诊断中的突破1. 技术原理2. 实际应用3. 性能表现 三、深度学习在医学影像诊断中的惊人表现1. 提高疾病诊断准确率2. 辅助制定治疗方案 四、深度学习对医疗行业的影响和推动作用 一、引言 随着…

k8s——安全机制

一、安全机制说明 Kubernetes作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。API Server是集群内部各个组件通信的中介&#xff0c; 也是外部控制的入口。所以Kubernetes的安全机制基本就是围绕保护API Server来设计的。 比如 kubectl 如果想…

jadx-gui-1.5 反编译工具使用教程 反混淆 Java android 查看签名

JADX&#xff1a;JADX是一个强大的反编译工具&#xff0c;它支持命令行和图形界面操作。除了基本的反编译功能外&#xff0c;JADX还提供了反混淆功能&#xff0c;有助于提高反编译后代码的可读性。 在Android开发和安全分析领域&#xff0c;反编译工具扮演着至关重要的角色。这…

Python | Leetcode Python题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; class Solution:def sumNumbers(self, root: TreeNode) -> int:if not root:return 0total 0nodeQueue collections.deque([root])numQueue collections.deque([root.val])while nodeQueue:node nodeQueue.popleft()num numQueue.p…

Vue3+vite部署nginx的二级目录

修改router访问路径 const router createRouter({history: createWebHistory(/mall4pc-bbc/),routes: [XXX,] })配置package.json文件 "build:testTwo": "vite build --mode testing --base/mall4pc-bbc/", 执行打包命令 npm run build:testTwo 打包出…

搭dg mount报错ora-01103 database name XXXX in control file 处理

问题 处理方法 RMAN> shutdown Oracle instance shut down RMAN> [oracleprimary1 ~]$ cd $ORACLE_HOME/dbs [oracleprimary1 dbs]$ ls hc_racpm1.dat hc_stdg11.dat id_racpm1.dat init.ora initstd.ora orapwstdg11 spfilestdg11.ora [oracleprimary1 dbs]$ v…

压力测试-性能指标-Jmeter使用-压力测试报告

文章目录 1.压测目的2.性能指标3.Jmeter3.1Jmeter使用3.1.1 运行Jmeter3.1.2 添加线程组3.1.3设置HTTP请求3.1.4 设置监视器 3.2 查看Jmeter压测结果3.2.1 查看结果树3.2.2 查看汇总报告3.2.3 查看聚合报告3.2.4 查看汇总图 1.压测目的 内存泄漏&#xff1a;OOM&#xff0c;重…

智慧园区整体解决方案(PPT文件)

智慧园区整体建设方案旨在通过整合园区内外部资源&#xff0c;提升园区的信息化、智能化水平&#xff0c;以创新驱动经济发展方式转变&#xff0c;提高经济增长质量效益。方案主要包括以下几个方面&#xff1a; 基础设施建设&#xff1a;实现园区内网络全覆盖&#xff0c;包括宽…

解决国内无法访问huggingface.co

在国内无法访问 https://huggingface.co 时&#xff0c;可以使用国内的镜像站点&#xff1a; HF-Mirror - Huggingface 镜像站加速访问Hugging Face的门户。作为一个公益项目&#xff0c;我们致力于提供稳定、快速的镜像服务&#xff0c;帮助国内用户无障碍访问Hugging Face的…

使用SourceTree切换不同的托管平台

背景&#xff1a;sourcetree一开始绑定了gitee&#xff0c;想拉取github的项目时拉取不了 原因&#xff1a;git绑定的账号&#xff08;邮箱&#xff09;、密码不一致 解决办法&#xff1a; 重新设置账号密码 在windows种可找到下面的文件夹&#xff0c;进行删除 C:\Users\US…

乙二醇水溶液物性参数

1.1 乙二醇水溶液的冰点、沸点 乙二醇水溶液作为重要的载冷剂&#xff0c;其物理性质对设备和系统的设计都十分重要&#xff0c;下面是乙二醇水溶液的冰点沸点和其浓度的关系。&#xff08;数据来源 ASHRAE 手册 2005&#xff09; 1.2 乙二醇水溶液粘度 乙二醇水溶液作为重要…

Linux Ext2/3/4文件系统

文章目录 前言一、Linux文件系统简介1.1 简介1.2 Linux File System Structure1.3 Directory Structure 二、Ext2/3/4文件系统2.1 Minix2.2 EXT2.3 EXT22.4 EXT32.5 EXT4 三、EXT Inode参考资料 前言 这篇文章介绍了Linux文件系统的一些基础知识&#xff1a;Linux 文件系统简介…

ArcGIS Pro SDK (一)环境配置

ArcGIS Pro SDK &#xff08;一&#xff09;环境配置 安装 .NET6 SDK - Download .NET 6.0 (Linux, macOS, and Windows) (microsoft.com) 安装 ArcGIS Pro 3.0&#xff08;需要详细ArcGIS安装pj请留言&#xff09; 安装 Visual Studio 2022 - Visual Studio: 面向软件开发人…

计算机网络基础-VRRP原理与配置

目录 一、了解VRRP 1、VRRP的基本概述 2、VRRP的作用 二、VRRP的基本原理 1、VRRP的基本结构图 2、设备类型&#xff08;Master&#xff0c;Backup&#xff09; 3、VRRP抢占功能 3.1&#xff1a;抢占模式 3.2、非抢占模式 4、VRRP设备的优先级 5、VRRP工作原理 三…

节点间通路

题目链接 节点间通路 题目描述 注意点 图是有向图节点编号大于等于 0 小于 n图中可能存在自环和平行边 解答思路 初始想到的是使用广度优先遍历&#xff0c;从start开始&#xff0c;存储每个点所能到达的其他节点集合&#xff0c;直到到达target或者不能到达新的节点为止&…

Linux-桌面操作系统在服务器上未关闭休眠机制,使其开机半小时左右死机无法远程ssh连接

故障表述 操作系统:ubuntu desktop 18.04 异常描述:开机半小时左右死机 1、登录iBMC查看硬件无异常 2、登录ubuntu desktop 18.04操作系统,导出日志文件syslog、dmesg、lastlog(路径:/var/log),操作系统在11月8号~11月9号之间出现异常 经分析操作系统日志文件,操作系…