给定一个不含重复数字的数组 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]]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析之后发现这道题还是在枚举所有的可能性,那么准备采用回溯法。
抽象树中,可以看出排列中[1,2]和[2,1]是两种不同的选择,而在组合中是一样。那就不需要使用startIndex来控制。组合问题其实取数有一规律都是从前往后选,但是排序不一样的,那么在取值的时候就需要判断之前的数是否被选了。
递归的参数和返回值
nums:输入的数组
path:存放单次排序的路径
List<List<Integer>> res = new ArrayList<>();
void backtracing(int[] nums,List<Integer> path);
递归的终止条件
递归的层数是确定的,只要所有的数都排列了就结束了
if(path.size() == nums.length){
res.add(path);
return;
}
递归的单层逻辑
每一次取值都需要从头到尾选择,不能取已经取过的值,那怎么表示值已经取过了?path的路径之中有就说明已经取值了,没有就说明还没有取过值
还可以设置一个visited数组记录元素是否被访问过。
for(int i =0;i<nums.length;i++){
if(path.cantains(i))continue; //表示已经取过了,那就不能去跳到下一个
path.add(i);
backtracing(nums,path);
path.remove(path.size()-1);
}
代码
class Solution {
List<List<Integer>> res ;
public List<List<Integer>> permute(int[] nums) {
res = new ArrayList<>();
backtracing(nums,new ArrayList<>());
return res;
}
void backtracing(int[] nums,List<Integer> path){
if(path.size() == nums.length){
res.add(new ArrayList(path));
return;
}
for(int num:nums){
if(path.contains(num))continue;
path.add(num);
backtracing(nums,path);
path.remove(path.size()-1);
}
}
}
原文:https://www.cnblogs.com/rananie/p/14902365.html