全排列问题
给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案(力扣46)
输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
我们先进行一个手写那么,我们得到的规律是:
以1开头的排列有:[1,2,3] ,[1,3,2]
以2开头的排列有:[2,1,3] ,[2,3,1]
以3开头的排列有:[3,1,2] ,[3,2,1]
简单总结的公式就是
// 使用递归回溯方式解决这个问题,那么退出条件是什么
// 当 List<Integer> list 里面的元素个数等于传给我们数组的长度的时候
private void backtrack(){
if(nums.length == list.size()) {
// 将数据添加到结果上
res.add(new ArrayList<>(list);
}
// 不能满足条件就进行递归
// 其中first表示list中第几个,同时用来记录那些数组已经用过了
for(int i = first; i < nums.length; i++){
// 做选择
// backtrack(路径, 选择列表)
// 撤销选择
}
}
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> output = new ArrayList<>();
// 将数组变成list结构
for(int num: nums){
output.add(num);
}
int n = nums.length;
backtrack(res, output, 0, n);
return res;
}
private void backtrack(List<List<Integer>> res, List<Integer> output, int first, int n){
if(first == n){
res.add(new ArrayList<>(output));
}
for(int i = first; i < n; i++){
Collections.swap(output, i, first);
backtrack(res, output, first + 1, n);
Collections.swap(output, first, i);
}
}
}