直觉就是递归回溯。思路比如输入是{1,2,3,4}就是{1,2,3,4}里任意一个元素剩下所有元素全排列。就是1{2,3,4}的全排列2{1,3,4}的全排列3{1,2,4}的全排列4{1,2,3}的全排列。step01: 定义递归问题dps(int nums[])为nums[]里所有元素的全排列step02语义其实在一开始思考思路的时候已经写出来了step03: dps(int nums[]) for(int i0; inums.length;i){idps(nums[i]之外的其他元素)}再就是需要回溯这个很好判断在《递归篇》里讲过是否需要回溯的判断。因为每次进入子递归都要去掉当前递归用到的元素nums[i]我本来想的是用set.remove的方式。致命的错误在于集合在for循环里不能remove。这里就用到了标记数组int[] usedused[i]0标记为没用过used[i]标记为用过。class Solution { public ListListInteger permute(int[] nums) { int[] usednew int[nums.length]; //构造递归参数 ListListInteger result new ArrayList(); //构造递归参数 ListInteger temp new ArrayList(); //构造递归参数 dps(nums,used,temp,result); return result; } public void dps(int[] nums, int[] used, ListInteger temp, ListListInteger result){ //递归出口 if(temp.size()nums.length){ result.add(new ArrayList(temp)); //坑别写成result.add(temp);这样的话结果全是[[][][][]] return; } //递推关系 for(int i0;inums.length;i){ if(used[i]0){ used[i]1; //引用传递只能写成穿脱原则 temp.add(nums[i]); //引用传递只能写成穿脱原则 dps(nums,used,temp,result); temp.remove(temp.size()-1); used[i]0; } } } }还有一点要注意的是递归出口那里因为temp是引用传递所以要把他的值拷贝一下重新new一个对象再放进result里如果写成result.add(temp)的话最后得到的是一片空集合。