当前位置: 首页 > news >正文

LeeCode 46. 全排列

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

答案:

static int getArrangeCount(int n) { // n个不同的数,全排列方法数,为 n * (n - 1) * ... * 1if (n == 1)return 1;return n * getArrangeCount(n - 1);
}/**
* arr为其中的一个排列。
* currIdx标识当前要确认的哪个索引的数
*/
static void pailie(int** res, int totalSize, int* currCount, int* nums, int* arr, int arrSize, int currIdx, int* used) {//printf("totalSize: %d, *currCount:%d, currIdx: %d\n", totalSize, *currCount, currIdx);if (*currCount == totalSize) {// 说明全部任务完成了printf("all finish 实际没调用到这一行\n");return;}if (currIdx == arrSize) {//printf("一个排列准备好了\n");// 一个排列准备好了// 复制一个数组出来,原始数组还有用,后面需要回溯尝试其他排列方案int* arr_ = (int*)malloc(arrSize * sizeof(int));if (!arr_) return;memcpy(arr_, arr, arrSize * sizeof(int));//printf("打印一个排列:");//printArr(arr_, arrSize);//printf("*currCount: %d\n", (*currCount));*(res + *currCount) = arr_; // 保存结果*currCount = *currCount + 1;//printf("new *currCount: %d\n", (*currCount));return;}//printf("currIdx: %d\n", currIdx);for (int i = 0; i < arrSize; i++) {if (used[nums[i] + 10]) {// 已使用过该数//printf("已使用过%d\n", nums[i]);continue;}//printf("没使用过%d\n", nums[i]);arr[currIdx] = nums[i]; // 使用这个数//printf("arr[%d] = %d\n", currIdx, nums[i]);used[nums[i] + 10] = 1; // 标识这个数用过了//printf("nums[0] used: %d, nums[1] used:%d, nums[2] used:%d\n", used[nums[0] + 10], used[nums[1] + 10], used[nums[2] + 10]);// 再确认下一位pailie(res, totalSize, currCount, nums, arr, arrSize, currIdx + 1, used);// 回溯,即回退,不使用该数字。然后会尝试使用其他数字used[nums[i] + 10] = 0;//printf("回退后:");//printf("nums[0] used: %d, nums[1] used:%d, nums[2] used:%d\n", used[nums[0] + 10], used[nums[1] + 10], used[nums[2] + 10]);}
}/*** 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** permute(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { // LeeCode46 全排列int count = getArrangeCount(numsSize); // 全排列方法数*returnSize = count;*returnColumnSizes = (int*)malloc(count * sizeof(int));if (*returnColumnSizes == NULL) {return NULL;}for (int i = 0; i < count; i++) {*(*returnColumnSizes + i) = numsSize; // 返回的每个数组的长度都为numsSize}int** res = (int**)malloc(count * sizeof(int*));if (!res) return NULL;int* arr = (int*)malloc(numsSize * sizeof(int));if (!arr) return NULL;// 根据题意, nums 中的所有整数 互不相同, 且-10 <= nums[i] <= 10. 所以排列数字的时候使用used数组标识哪些数已使用过了// used[0]标识-10是否使用过。 userd[20]标识10是否使用过int used[21] = { 0 };int currCount = 0;pailie(res, count, &currCount, nums, arr, numsSize, 0, used);free(arr); // 这个临时数组不需要了,释放内存return res;
}

测试代码:

void printArr(int** arr, int size, int* returnColumnSizes) {printf("[");int isFirst = 1;for (int i = 0; i < size; i++) {if (isFirst) {isFirst = false;}else {printf(",");}int isSubFirst = 1;printf("[");for (int j = 0; j < returnColumnSizes[i]; j++) {if (isSubFirst) {isSubFirst = false;}else {printf(",");}printf("%d", arr[i][j]);}printf("]");}printf("]\n");
}void printArr(int* arr, int size)
{printf("[");int isFirst = 1;for (int i = 0; i < size; i++) {if (isFirst) {isFirst = false;}else {printf(",");}printf("%d", arr[i]);}printf("]\n");
}void testLeeCode46(void) { // LeeCode46全排列int nums[] = { 1, 2, 3 };int numsSize = 3;int returnSize; // 用于接受结果二维数组的长度。int* returnColumnSizes; // 用来接受结果二维数组的每个元素(即子数组)的长度int** res = permute(nums, numsSize, &returnSize, &returnColumnSizes);printArr(res, returnSize, returnColumnSizes);// 释放内存for (int i = 0; i < returnSize; i++) {free(res[i]);}free(res);free(returnColumnSizes);
}

打印:

ok. 提交到LeeCode:

ok.  总结:使用的回溯算法(即深度优先算法)将所有的排列都穷举出来。

http://www.lryc.cn/news/616383.html

相关文章:

  • 冒泡排序实现以及优化
  • 20250810 | 深度学习入门笔记1
  • 大型动作模型LAM:让企业重复任务实现80%效率提升的AI技术架构与实现方案
  • 五种 IO 模型与阻塞 IO
  • 数组中的第K个最大元素
  • MyBatisPlus插件原理
  • Leetcode 3646. Next Special Palindrome Number
  • 代码随想录算法训练营第六十天|图论part10
  • 【Nginx②】 | Nginx部署前端静态文件指南(基于虚拟机环境)
  • 浏览器CEFSharp88+X86+win7 之多页面展示(四)
  • NodeJs学习日志(4):路由合并_环境配置_常用文件目录
  • element-ui el-progress在有小数的情况下,会换行显示。解决不换行的问题。
  • iceberg安装部署
  • Rust面试题及详细答案120道(11-18)-- 控制流与函数
  • vulnhub-Drippingblues靶机
  • 通过Certbot自动申请更新HTTPS网站的SSL证书
  • 瑞芯微 RK3588 平台驱动开发 学习计划
  • CST支持对哪些模型进行特征模仿真?分别有哪些用于特征模分析的求解器?
  • C语言——深入理解指针(二)
  • 【东枫科技】FR3 可扩展测试平台,适用于 6G 研究与卫星通信,高达 1.6 GHz 的带宽
  • 【秋招笔试】2025.08.09美团秋招算法岗机考真题-第三题
  • Python 的浅拷贝 vs 深拷贝(含嵌套可变对象示例与踩坑场景)
  • OpenGL VAO 概念、API 和示例
  • 每日一题:使用栈实现逆波兰表达式求值
  • TypeScript中的type和interface的区别是什么?
  • 从街亭失守看管理
  • WAV音频数据集MFCC特征提取处理办法
  • 【MySQL——第三章 :MySQL库表操作】
  • 如何选择适合自己电商业务的 API?​
  • DBAPI 实现不同角色控制查看表的不同列