1、描述
给定一个 没有重复 数字的序列,返回其所有可能的全排列
例:输入:[1, 2, 3]
输出:[
[1, 2, 3] ,
[1, 3, 2] ,
[2, 1, 3] ,
[2, 3, 1] ,
[3, 1, 2] ,
[3, 2, 1]
]
2、算法
利用回溯法探索求排列
什么是回溯法?
答:回溯法是一种通过探索所有可能的候选解来找出所有的解的算法,如果候选解被确认 不是 一个解(或 至少不是 最后一个 解),回溯算法回通过上一步进行一些变化抛弃该解,即 回溯,并再次尝试。
回溯步骤:
1)使用第一个整数的索引作为参数 first
2)如果第一个整数索引 等于 n,意味着当前排列已完成
3)遍历索引 first ~n-1的整数
(1)在排列中放置第i个整数,即交换nums 的first 和 i 下标对应的整数
(2)继续生成从第i 个整数开始的所有排列 即递归 first+1
(3)现在回溯 几还原(1)中交换的整数
func permute(_ nums: [Int]) -> [[Int]] {
var output : [[Int]] = []
var num_list : [Int] = []
for num in nums {
num_list.append(num)
}
let n = nums.count
backTrack(n, &num_list, &output, 0)
return output
}
private func backTrack(_ n : Int, _ nums : inout [Int], _ output : inout [[Int]], _ first : Int){
//如果第一个索引为n 即当前排列已完成
if first==n {
//将生成的排列加入数组
addArr(&output, nums)
}
for i in first..<n {
//在排列中放置第i个整数
nums.swapAt(first, i)
//继续生成从第i个整数开始的所有排列
backTrack(n, &nums, &output, first+1)
//回溯,还原交换的数据
nums.swapAt(first, i)
}
}
//将生成的排列加入数组
private func addArr(_ output : inout [[Int]], _ nums : [Int]){
output.append(nums)
}
调用:print(Algorithm.permute([1, 2, 3]))
运行结果:
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]]