Leecode刷题C语言之全排列②

ops/2025/2/9 3:23:31/

执行结果:通过

执行用时和内存消耗如下:

 

int* path;
int pathTop;
int** ans;
int ansTop;
int cnt[8];//标记path中是否已有此索引值,这也是同46题不同点
void backTracking(int* nums,int numsSize,int startIndex,int** returnColumnSizes){if(pathTop==numsSize){(*returnColumnSizes)[ansTop] = pathTop;ans[ansTop] = (int*)malloc(sizeof(int)*pathTop);for(int i = 0;i<pathTop;i++){//装入子集ans[ansTop][i] = path[i];}ansTop++;return;}int cnt_1[21];//同一层相同元素只能读一次memset(cnt_1,0,sizeof(cnt_1));//递归组合for(int i = startIndex;i<numsSize;i++){if(cnt[i]||cnt_1[nums[i]+10]) continue;//此索引本轮已访问过或此值在此层已访问过path[pathTop++] = nums[i];cnt[i] = 1;//本组合相应索引位置已访问cnt_1[nums[i]+10] = 1;//本层相同元素已访问backTracking(nums,numsSize,0,returnColumnSizes);cnt[i] = 0;//退出路径则解除标记pathTop--;}
}
int** permuteUnique(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {memset(cnt,0,sizeof(cnt));path = (int*)malloc(sizeof(int)*8);//开到最大ans = (int**)malloc(sizeof(int*)*10000);*returnColumnSizes = (int*)malloc(sizeof(int)*10000);pathTop = 0;ansTop = 0;//从0开始递归backTracking(nums,numsSize,0,returnColumnSizes);*returnSize = ansTop;free(path);return ans;
}

解题思路:

这段代码实现的是求解给定整数数组 nums 的所有不重复排列的算法。它使用了回溯算法(Backtracking)来解决这个问题。以下是解题思路的详细步骤:

  1. 初始化变量:
    • int* path;:用于存储当前排列路径。
    • int pathTop;:表示当前路径中的元素数量。
    • int** ans;:用于存储所有排列的结果。
    • int ansTop;:表示结果中排列的数量。
    • int cnt[8];:用于标记在 path 中是否已有某个索引值,防止在同一排列中重复使用同一元素(由于题目可能未明确数组大小,这里假设最大为8,实际应用中应根据具体情况调整)。
  2. 辅助函数 backTracking:
    • 参数:int* nums(输入数组),int numsSize(数组大小),int startIndex(当前递归的起始索引),int** returnColumnSizes(用于存储每个排列的长度)。
    • 终止条件:当 pathTop == numsSize 时,表示找到一个完整排列,将其存储到 ans 中,并更新 ansTop 和 *returnColumnSizes
  3. 去重机制:
    • 在每一层递归中,使用一个临时数组 cnt_1[21](考虑到 nums[i] 可能为负数,所以偏移10以避免数组越界)来记录当前层已经访问过的元素值,防止在同一层中重复使用相同的元素值。
    • cnt 数组用于记录在整个排列过程中,某个索引是否已经访问过,防止在排列中重复使用同一元素。
  4. 递归过程:
    • 从 startIndex 开始遍历数组 nums
    • 如果当前元素索引已被访问过(cnt[i])或当前元素值在同一层已被访问过(cnt_1[nums[i]+10]),则跳过该元素。
    • 将当前元素加入 path,标记该索引和该元素值已被访问。
    • 递归调用 backTracking,注意下一层递归的 startIndex 应为0,因为我们需要考虑所有元素的所有可能位置,而不是仅考虑剩余元素。
    • 回溯:撤销选择,即将当前元素从 path 中移除,并取消对该索引和元素值的标记。
  5. 主函数 permuteUnique:
    • 初始化 cnt 数组、path 数组、ans 数组和 *returnColumnSizes
    • 调用 backTracking 函数开始递归。
    • 设置 *returnSize 为 ansTop,即排列的总数。
    • 释放 path 数组的内存,返回 ans 数组。
  6. 内存管理:
    • 注意在返回结果之前,所有动态分配的内存(如 path 和 ans 中的每个排列)都应当被正确管理。在这个实现中,path 在返回结果前被释放,但返回的 ans 数组及其内容需要由调用者负责释放,以避免内存泄漏。

这个算法的关键在于通过 cnt 和 cnt_1 两个数组来有效地避免生成重复的排列,同时通过回溯算法确保能够遍历所有可能的排列。


http://www.ppmy.cn/ops/156872.html

相关文章

自动化软件测试的基本流程

一、自动化测试的准备 1.1 了解测试系统 首先对于需要测试的系统我们需要按照软件需求说明书明确软件功能。这里以智慧养老系统作为案例进行测试&#xff0c;先让我们看看该系统的登录界面和用户管理界面。 登录界面&#xff1a; 登录成功默认界面&#xff1a; 用户管理界面…

Jenkins基础篇 - Jenkins介绍与安装示例

文章目录 1. Jenkins介绍2. Jenkins安装2.1 使用War文件安装2.1.1 硬件要求2.1.2 软件要求2.1.3 安装Java2.1.4 安装Jenkins 3 安装后设置向导3.1 解锁Jenkins3.2 自定义Jenkins插件3.3 创建第一个管理员用户3.4 实例配置3.5 Jenkins已就绪&#xff01;&#xff01;&#xff01…

VC播放mp3的方法

1、使用msi库 #include <mmsystem.h> #pragma comment(lib,"winmm.lib") .......//打开文件MCI_OPEN_PARMS mciOpen; mciOpen.lpstrDeviceType _T("mpegvideo"); mciOpen.lpstrElementName _T("c://1.mp3"); MCIERROR mciError mci…

【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目

解决idea至少创建jdk17项目 问题 idea现在只能创建最少jdk17&#xff0c;不能创建java8了吗?解决 问题 idea现在只能创建最少jdk17&#xff0c;不能创建java8了吗 我本来以为是 IDEA 版本更新导致的 Bug&#xff0c;开始还没在意。 直到我今天自己初始化项目时才发现&am…

102,【2】buuctf web [第二章 web进阶]XSS闯关

进入靶场 点击看看 前情提要 如果只想得到flag时 不想做题时&#xff0c;把level由1不断往下修改就可通过一关又一关 最后在url处修改level为7即可得到flag 通过做题破解每一关的话&#xff0c;就如下 操作 第一关 修改url <script>alert(xss)</script> 第二…

《具身智能时代:机器人具身抓取技术的前沿探索与应用综述》

自2022年GPT等大模型的爆发以来&#xff0c;人工智能领域以语言模型为代表的预训练模型在多个领域掀起了创新浪潮。到了2024年&#xff0c;DeepSeek等新技术进一步加速了具身智能的发展&#xff0c;特别是在机器人领域&#xff0c;预训练模型的引入深刻改变了传统的感知、决策和…

一次报警了解:direct path read、enq: KO - fast object checkpoint

背景 今天突然接到订单超时报警&#xff0c;数据库的状态确实惊出一身冷汗&#xff0c;查看系统日志正常&#xff0c;数据库日志正常&#xff0c;load 1-3之间&#xff0c;Session 连接200左右&#xff0c;未发现有负载。于是生成一个ASH报告&#xff0c;感觉比平时要慢很多&am…

STM32 简介

STM32 简介 1. STM32性能2. STM32命名规则3. STM32分类4. 传统嵌入式方向 1. STM32性能 STM32 的优异性体现在如下几个方面&#xff1a; 超低的价格。8 位机的价格&#xff0c;32 位机的性能&#xff0c;是 STM32 最大的优势。超多的外设。STM32 拥有包括&#xff1a;FMC、TIME…