「前端每日一问(59)」输出给定一组数字的全排列

187 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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(缓存路径,数据)
    回退,撤回选择的数据
  }
}

图解:

1631607821-lOapRO-file_1631607821406.png

图片来源: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! 上班“认真工作”的神器 🐶

第一次提交结果

image.png

使用空间换时间后的运行结果

image.png

结尾

阿林水平有限,文中如果有错误或表达不当的地方,非常欢迎在评论区指出,感谢~

如果我的文章对你有帮助,你的👍就是对我的最大支持^_^

我是阿林,输出洞见技术,再会!

上一篇:

「前端每日一问(58)」请使用深度优先搜索遍历一棵 DOM 树

下一篇:

「前端每日一问(60)」删除有序数组中的重复项