思路分析:容易陷入自己的解题思路模式(想自己搞个标志来实现调用情况,可是不知道如何复原,被绕晕了),官方题解的就是妙a,考虑利用二叉树不停地交换位置来实现全排列!!!!
for循环—回溯:横向遍历;递归:纵向遍历!!!
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> container=new ArrayList<List<Integer>>();
List<Integer> onelist=new ArrayList<Integer>();//每次添加的一个数据组列
for(int n:nums){
onelist.add(n);//将原始顺序的数组放置列中
}
int length=nums.length;
backtrack(length,onelist,container,0);
return container;
}
//first这个是个只与后面交换de头位置,first与i位置进行交换,注意回溯的时候需要还原位置
public void backtrack(int length,List<Integer> onelist,List<List<Integer>> container,int first){
if(first==length){
container.add(new ArrayList<Integer>(onelist));//深拷贝
return;//递归结束,不加这句时,在进入for循环判断也会退出(少执行一条判断语句)
}
for(int i=first;i<length;i++){
Collections.swap(onelist,first,i);//交换列表中的指定位置
backtrack(length,onelist,container,first+1);//递归继续移动要交换的起始指针,纵向递归
//开始回溯
Collections.swap(onelist,first,i);//返回原样横向回溯,进行下一次的for循环的i++,此时first和别的元素交换位置
}
}
}
补充知识:Java中res.add(list)和res.add(new ArrayList<Integer>(list))的区别
res.add(new ArrayList<>(path))和res.add(path)的区别