分析
与“子集”相比,元素相同、次序不同的集合不再只算一种情况。
求取全排列,即数组元素的所有排列可能性。方法是让所有的元素都有机会在第一次取到,然后在剩下的元素里面重复这个步骤,直到所有元素都被取到。
回溯的横向:遍历整个数组,已经取到的元素跳过,取一个未加入的元素,向下递归,恢复现场,遍历右边的元素。
回溯的纵向:深度一定是数组的长度
import java.util.ArrayList;
class Solution {
/*
回溯的含义:回到过去,撤销选择,状态重置,恢复现场。
全排列 第一位有n种可能,第二位有n-1种可能...最终的结果是n!
建一个boolean数组保存每个数的有没有被使用过。
建一个方法,每次都新增一个未使用过的数,递归调用自己,当长度等于nums的长度,保存结果,回退到上一步继续递归,直到递归结束。
*/
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
if(nums == null || nums.length == 0){
return list;
}
process(nums,0,new boolean [nums.length],new ArrayList<>(),list);
return list;
}
public void process(int[] nums,int index,boolean[] judge,List<Integer> li,List<List<Integer>> list){
if(index == nums.length){
list.add(new ArrayList<>(li));/*
list不能直接添加li,因为存入的li是集合li的地址,
当li集合发生变化,list里的li也会同时发生变化。
new ArrayList<>(li) :用参数li的元素构造一个新的ArrayList集合,元素顺序是按照li的迭代顺序。
*/
return ;
}
for(int i = 0;i < nums.length;i++){
if(!judge[i]){
li.add(nums[i]);
judge[i] = true;
process(nums,index+1,judge,li,list);
li.remove(li.size()-1);//回退到上一步的初始状态
judge[i] = false;
}
}
return ;
}
}
版权声明:本文为weixin_43260719原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。