Leetcode前端必会系列:全排列

65 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

引言

算法的技能对于程序员是百益而无一害,作为程序员无论是前端还是后端算法技能对于我们都是十分十分的重要,我将陆续整理并讲解前端程序员必须掌握的经典算法。

题目描述

给定一个不含重复数字的数组 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. 定义递归函数,递归的出口是临时数组的长度等于目标数组个数就保存
  3. 递归内部通过回溯的设计思想不断地判断改元素是否访问,如果访问了退出,否则添加到访问数组并标记访问过了。
  4. 返回最终的结果。

解答

   var permute = function(nums) {

    let path = []

    let res = []

    const main = used => {

        if(path.length === nums.length) res.push([...path])

        for(let i=0;i<nums.length;i++) {

            if(used[i]) continue

            used[i] = true

            path.push(nums[i])

            main(used)

            used[i] = false

            path.pop()

        }

    }

    main()

    return res

};

整体算法的设计是基于回溯完成的。通常回溯的设计还是比较抽象的,因此我们需要按照回溯算法设计的三要素完成题目的分解就可以解答题目了。

总结

通过对全排列的讲解,大家学到了进行问题的解决。通过回溯算法巧妙计算可以优雅的在低时间和空间复杂度下完成任务。