leetcode之46全排列Golang

题目描述

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

算法

本题使用回溯算法,还是提一句回溯算法的核心思想,就是采用深度遍历的思维,一直深度遍历到最后的结果,并且在这个过程中记录每一步的中间结果,中间结果的作用是为了让我们能够往回退。到了最后的时候,判断最后结果是否满足条件,如果满足条件,那么就记录这个结果,如果不满足条件,那么就舍弃这个结果。再然后,利用中间结果向回退一步,走其他路径,继续计算出其他结果,并且再次判断。

本题的算法如下:

  • 对于第一个数,可以采用任意数组中任意一个数作为开头,所以遍历数组取出一个数,这一步得到的中间结果就是遍历出的这个数,并且得到新的数组,就是原入口参数数组去除掉我们遍历出的数的数组,利用这个数组,再次遍历取出下一个数
  • 如果入口参数的数组中不包含任何元素,那么说明我们把入口参数数组已经深度遍历完成,就记录这个结果
  • 如果入口参数数组还包含元素,那么我们遍历入口参数数组中剩下的元素,依次取出一个元素追加到结果中,作为中间结果。

代码

func permute(nums []int) [][]int {
	res := make([][]int, 0)
	tmp := make([]int, 0)
	var recursion func(leftNums, tmpRes []int)
	recursion = func(leftNums, tmpRes []int) {
		if len(leftNums) == 0 {
			res = append(res, tmpRes)
			return
		}
		for index, value := range leftNums {
			newTmpRes := append(tmpRes, value)
			newLeftNums := make([]int, len(leftNums)-1)
			count := 0
			for i, v := range leftNums {
				if i != index {
					newLeftNums[count] = v
					count++
				}
			}
			// newLeftNums := append(leftNums[:index], leftNums[index+1:]...)
			// 不使用上面这行代码的原因是append会改变leftNums底层数组的值
			recursion(newLeftNums, newTmpRes)
		}
	}
	recursion(nums, tmp)
	return res
}
posted @ 2020-11-13 09:15  胖胖咩  阅读(659)  评论(0)    收藏  举报