当前位置: 首页 > 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.dtcms.com/a/324852.html

相关文章:

  • 【树\思维】P1395 会议
  • 33.搜索旋转排序数组
  • Agno智能体框架简单使用
  • docker等基础工具使用
  • 从策略梯度到 PPO
  • java中的继承
  • Flutter开发 LinearProgressIndicato、CircularProgressIndicator
  • django基于Python的设计师作品平台的数据可视化系统设计与实现
  • QT的常用控件说明
  • Java基础—解析注解
  • 游戏常用运行库合集:一键解决游戏兼容性问题
  • 锂电池SOH预测 | 第35讲 Matlab基于BiLSTM的锂电池健康状态估计(锂电池SOH预测),附锂电池最新文章汇集
  • scanpy单细胞转录组python教程(二):单样本数据分析之数据质控
  • springboot的基础要点
  • 【Task3】【Datawhale AI夏令营】多模态RAG
  • 3.4路由守卫
  • Words or Vision Do Vision-Language Models Have Blind Faith in Text
  • Java中new的相关知识
  • nginx-主配置文件
  • Redis的批处理优化
  • 【高等数学】第八章 向量代数与空间解析几何——第六节 空间曲线及其方程
  • ECP HRFORM 提示ADS服务异常
  • 【嵌入式电机控制#补充3】SDK电机控制台的功能
  • C9800在NAT设备之后怎么办?
  • [创业之路-541]:经营分析会 - 企业的经营分析会,研发负责人负责提供哪些信息?
  • Linux810 shell 条件判断 文件工具 ifelse
  • 【牛客刷题】小红的项链(字节跳动面试题)
  • Linux操作系统从入门到实战(十七)进程与进程基本概念
  • doubletrouble靶机攻略
  • Docker 数据卷的核心原理与管理逻辑