数据结构与算法之递归:LeetCode46.全排列(Typescript版)
- 其他
- 2025-07-21 19:23:44

全排列 leetcode /problems/permutations/ 描述 给定一个不含重复数字的数组 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] <= 10nums 中的所有整数 互不相同 算法实现
1 )回溯1: 基于数组
function permute(nums: number[]): number[][] { const res: number[][] = []; // 回溯函数 const backtrack = (path: number[]) => { // 满足当前条件 if(path.length === nums.length) { res.push(path); return; } // 遍历 for(let i = 0; i < nums.length; i++) { if(path.includes(nums[i])) continue; backtrack(path.concat(nums[i])); } } backtrack([]); return res; } 时间复杂度:O(n*n!) 假设输入数组的长度为 n遍历每个元素的时间复杂度为 O(n)对于每个元素,都会进行递归调,假设数组中有 n 个不同的元素那么对于每个元素,都会有 n-1 个可能的选择,然后对于每个选择,又会有 n-2 个可能的选择,以此类推因此,递归的时间复杂度可以表示为 O(n!)。在每一层递归中,都会进行一次包含操作(includes),其时间复杂度为 O(n)。综合考虑,这段代码的时间复杂度为 O(n * n!),其中 n 表示输入数组的长度。需要注意的是,这里的时间复杂度分析基于平均情况。在最坏情况下,全排列的数量是 n!,因此在最坏情况下,时间复杂度为 O(n * n!)注意: n的阶乘公式: n! = 1*2*3*...*(n-1)*n 空间复杂度:O(n) 递归,堆栈,不是常量,是线性增长的是递归的层数2 )回溯2: 基于交换
function permute(nums: number[]): number[][] { const res: number[][] = []; const backtrack = function(start: number) { if (start === nums.length - 1) { res.push([...nums]); return; } for (let i: number = start; i < nums.length; i++) { [nums[i], nums[start]] = [nums[start], nums[i]]; // 交换 backtrack(start + 1); // 下一个数 [nums[i], nums[start]] = [nums[start], nums[i]]; // 交换撤销 } } backtrack(0); // 从 0 开始 return res; }; 这个问题可以看作有 n 个排列成一行的空格,我们需要从左往右依此填入题目给定的 n 个数,每个数只能使用一次那么很直接的可以想到一种穷举的算法,即从左往右每一个位置都依此尝试填入一个数看能不能填完这 n 个空格,在程序中我们可以用「回溯法」来模拟这个过程时间复杂度:O(n*n!),其中 n 为序列的长度空间复杂度:O(n) 回溯算法、递归和深度优先遍历之间的关系它们通常在算法中一起使用,因为回溯算法通常使用递归来实现,并且常常涉及到深度优先遍历的思想。
回溯算法与递归
回溯算法是一种渐进式寻找并构建问题解决方案的策略。在回溯算法中,通常通过递归的方式来尝试所有可能的情况。当找到一个可能的解决方案时,它会继续探索下去,如果发现不符合条件,就会回溯到上一个状态,尝试其他可能的情况。因此,回溯算法通常使用递归来实现,因为递归天然地适合于处理这种尝试所有可能情况的问题。回溯算法与深度优先遍历(DFS)
回溯算法通常使用深度优先遍历的思想。在回溯算法中,我们会尝试一条路走到底,直到无法再继续下去,然后回溯到上一个状态,尝试其他的可能性。这与深度优先遍历的思想是一致的,深度优先遍历也是尽可能深地搜索树的分支,直到无法再继续为止然后回溯到上一个节点,继续搜索其他分支因此,回溯算法通常使用递归来实现,并且其思想与深度优先遍历密切相关。
在许多情况下,回溯算法可以被视为一种特殊的深度优先遍历。
数据结构与算法之递归:LeetCode46.全排列(Typescript版)由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“数据结构与算法之递归:LeetCode46.全排列(Typescript版)”
下一篇
火柴人版王者-Java