给定一个不含重复数字的数组 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/** 2 * @param {number[]} nums 3 * @return {number[][]} 4 */ 5var permute = function(nums) { 6 7};
参考答案:
先用 (1, 2, 3) 进行举例:
按顺序枚举每一位可能出现的情况,已经选择的数字在 当前 要选择的数字中不能出现(设置一个 visited 数组)。
这样的思路,可以用一个树形结构表示。而树上的每一个结点表示了求解全排列问题的不同的阶段,这些阶段通过变量的「不同的值」体现,这些变量的不同的值,称之为「状态」;
使用深度优先遍历有「回头」的过程,在「回头」以后, 状态变量需要设置成为和先前一样 ,因此在回到上一层结点的过程中,需要撤销上一次的选择,这个操作称之为「状态重置」;
使用编程的方法得到全排列,就是在这样的一个树形结构中完成 遍历,从树的根结点到叶子结点形成的路径就是其中一个全排列。
1/** 2 * @param {number[]} nums 3 * @return {number[][]} 4 */ 5var permute = function(nums) { 6 let len = nums.length, result = [], visited = new Array(len).fill(false); 7 8 const dfs = (nums, len, depth, path, visited) => { 9 // 遍历到叶子结点了,可以返回了 10 if(depth === len) { 11 result.push([...path]); 12 } 13 14 for(let i = 0; i < len; i++) { 15 // 如果没遍历过 16 if(!visited[i]) { 17 // 压入 path 数组,然后是否遍历过的数组此下标处变为 true 18 path.push(nums[i]); 19 visited[i] = true; 20 // 继续 dfs,直到最后一层 21 dfs(nums, len, depth + 1, path, visited); 22 // 进行回溯,还原,以便下一次使用 23 visited[i] = false; 24 path.pop(); 25 } 26 } 27 } 28 29 dfs(nums, len, 0, [], visited); 30 return result; 31};
最近更新时间:2024-08-10