【leet-code清晰解题思路💯✅】46. 全排列

80 阅读2分钟

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

题目描述

给定一个不含重复数字的数组 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 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

解题思路

  • 题目是让我们枚举全排列,第一种最直接的思路是写nums.length个for循环,如果没有重复的就继续,有重复的就跳过。这个时间复杂度为O(n^n)。
  • 题目是让我们枚举全排列,第二种思路便是dfs。用一个临时数组记录当前的顺序,另应严格数组记录哪些数已经放入临时数组。然后对所有数遍历,如果没有用到,就放入临时数组,然后递归下去。这个时间复杂度为O(n!)。
    • 直到所有的数都放入临时数组,便形成了一个顺序。将其放入答案数组即可。这里便需要再开一个int来记录当前有多少个数放入了临时数组即可。
    • 这里要注意的是,对于go,如果没有使用全局变量,递归时,对结果数组,需要传入并返回更新。否则不会更新,因为slice在append时,地址会变,所以算语言的一个小坑吧。
func permute(nums []int) [][]int {
   ans = make([][]int, 0)
   m := make([]bool, len(nums))
   tmp := make([]int, 0)
   dfs2(m, 0, nums, tmp)
   return ans
}

func dfs2(m []bool, n int, nums, tmp []int) {
   if n == len(nums) {
      t := make([]int, len(tmp))
      copy(t, tmp)
      ans = append(ans, t)
      return
   }
   for i := 0; i < len(nums); i++ {
      if m[i] == false {
         m[i] = true
         tmp = append(tmp, nums[i])
         dfs2(m, n+1, nums, tmp)
         tmp = tmp[:len(tmp)-1]
         m[i] = false
      }
   }
}

image.png