力扣面试150题--全排列
Day 71
题目描述
思路
回溯这类题还真不好理解 难点在于它的思路是什么,写代码很简单
举个例子 123,我们如何获取它的全排列。如下图
我们聚焦到数组的序号first,我们需要不重复的往这个first填数(并且不重复,考虑从左往右依次填入值),抽象到图里的意思是该空格的元素,依次和空格后的元素交换次序(还有一个不交换的情况)。每次进入下一层时,first+1,然后重复交换的做法,直到first==元素总数(即都指向最后一个元素)。
思路已经有了
我们来看看回溯的做题模板:
void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择 : 本层集合中的元素) {处理节点;backtracking(路径, 选择列表); // 递归撤销处理; // 回溯}
}
我们来依次填空,首先我们需要一个保存结果的数组res,以及一个存放每种清空的列表te,这些都定义在permute,
首先我们需要确定back函数的参数,res和te肯定需要,我们需要得到空格的位置吧 x,我们需要知道数组的长度吧 n。对于te我们需要提前往里面填入nums的值,因为我们需要不停交换嘛。
其次我们来看终止条件,根据我们上面的分析,只要first==列表元素总数就要要保存te的副本到res中,结束递归。
最后看,循环条件,我们需要从空格位置和其后每个元素交换位置,操作就很明显了就是交换,撤销就是换回来就行,back()移动空格处理。
class Solution {public static void back(int x,int n,List<List<Integer>>res,List<Integer>te){if(x==n){res.add(new ArrayList<Integer>(te));return;}for(int i=x;i<n;i++){Collections.swap(te,i,x);back(x+1,n,res,te);Collections.swap(te,x,i);}}public static List<List<Integer>> permute(int[] nums) {List<List<Integer>>res = new ArrayList<List<Integer>>();List<Integer>te = new ArrayList<Integer>();for (int i = 0; i < nums.length; i++) {te.add(nums[i]);}back(0,nums.length,res,te);return res;}
}