Day 71
题目描述

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