「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战」
全排列 Permutations
LeetCode传送门46. 全排列
题目
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.
Example:
Input: nums = [1,2,3]
Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
Input: nums = [0,1]
Output: [[0,1],[1,0]]
Input: nums = [1]
Output: [[1]]
复制代码
Constraints:
- 1 <= nums.length <= 6
- -10 <= nums[i] <= 10
- All the integers of nums are unique.
思考线
解题思路
我们用回溯法来解决这道题,先看一下什么是回溯法
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
我们以nums= [1, 2, 3]
为例子,来看一下整个回溯过程。
我们用DFS
来实现回溯.
在深度优先遍历中,我们用参数arr
来表示本次遍历排列的数组,如果arr
的长度和 nums
的长度相等,说明已经是我们想要的结果之一了,我们直接 把结果放入res
中即可。
我们遍历我们的检测数组nums
的每一个元素item
,若arr
中已经存在item
则不考虑该值,直接处理下一个值。
若item
没有在arr
中出现过。我们可以把它放入arr
内,并再次执行dfs
操作,并在得到dfs
结果后,把该元素回退出来以便进行其他可能性的尝试。
function permute(nums: number[]): number[][] {
// 回溯算法
let res: number[][] = []
function dfs(arr) {
if (arr.length === nums.length) {
// 注意,这里是push的不应该是arr,而是arr的拷贝[...arr]
res.push([...arr])
return
}
nums.forEach(item => {
if (arr.includes(item)) return;
arr.push(item)
dfs(arr)
arr.pop()
})
}
dfs([])
return res
};
复制代码
我们也可以利用javascript
这门语言的特性,不处理pop
的过程,直接找结果即可。
function permute(nums: number[]): number[][] {
const res: number[][] = [];
function dfs(arr: number[]) {
if(arr.length === nums.length) return res.push(arr);
nums.forEach(item => {
if(arr.includes(item)) return;
dfs([...arr, item])
})
}
dfs([])
return res;
};
复制代码
时间复杂度
O(n!): n为数组的长度
这就是我对本题的解法,如果有疑问或者更好的解答方式,欢迎留言互动。