一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第24天,点击查看活动详情。
本题难度:⭐ ⭐ ⭐ ⭐
本题类型:算法、手写
阿林最近忙爆了,真的没时间认真写文章了,但是再忙也不能忘了学习,不然就懈怠了,最近多更新点前端面试中出现的高频算法题吧,这个写起来简单。
题目描述
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。
原题地址:leetcode 46. 全排列
题目要求
输入: nums = [1,2,3]
输出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
输入: nums = [0,1]
输出: [[0,1],[1,0]]
输入: nums = [1]
输出: [[1]]
题目分析
回溯入门题目必刷题之一。
算法都是这样,难者不会, 会者不难。
第一次做这道题,不知道回溯的思想,可能会去暴力破解,到最后发现暴力破解根本写不出来,这很正常。
回溯类型的题目其实有刷题公式,套公式解决就行。
刷题模板:
function backTrack (缓存路径,数据) {
if (递归终止条件) {
存放结果
return
}
for (循环数据) {
选择一个值,添加进缓存路径
backTrack(缓存路径,数据)
回退,撤回选择的数据
}
}
图解:
图片来源:leetcode,侵删
编码实现
function permute (nums) {
let path = []
let res = []
return backTrack(res, path, nums)
}
function backTrack(res, path, nums) {
if (path.length === nums.length) {
res.push([...path])
return
}
for (let num of nums) {
if (path.includes(num)) {
continue
}
path.push(num)
backTrack(res, path, nums)
path.pop()
}
return res
}
不喜欢传递参数的,利用作用域规则,把递归函数 backTrack 写到 permute 函数里面,也可以,代码如下:
function permute(nums) {
let res = [], path = []
backTrack()
return res
function backTrack () {
if (path.length === nums.length) {
return res.push([...path])
}
for (let num of nums) {
if (path.includes(num)) {
continue
}
path.push(num)
backTrack()
path.pop()
}
}
}
当然,上面的写法是使用了 includes 这个 API ,其实可以空间换时间,用一个对象 used 来存储已经记录的值,代码如下:
function permute(nums) {
let res = []
let path = []
let used = {}
backTrack()
return res
function backTrack () {
if (path.length === nums.length) {
return res.push([...path])
}
for (let num of nums) {
if (used[num]) {
continue
}
path.push(num)
used[num] = true
backTrack()
path.pop()
used[num] = false
}
}
}
运行结果
vscode leetcode 插件 yyds! 上班“认真工作”的神器 🐶
第一次提交结果
使用空间换时间后的运行结果
结尾
阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
我是阿林,输出洞见技术,再会!
上一篇:
「前端每日一问(58)」请使用深度优先搜索遍历一棵 DOM 树
下一篇: