回溯法
核心思想: 将数组nums[]中的数字填入nums.length个空格中,每个数字只能使用一次(可用数组used[]标记数组nums[]中的数字是否已使用),空格填满即可得一个排列组合,放入结果集resList中。
注意: 回溯的时候要撤销空格填入的数字以及标记数组used[]的对应标记,并继续尝试其他没被标记过的数字
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> resList = new ArrayList<>();//结果集
List<Integer> res = new ArrayList<>();//排列组合
int count = 0;//已填数字的空格个数,count=nums.length表示空格已填满
boolean[] used = new boolean[nums.length];//标记数组,用于标记数组nums[]中的数字是否已使用
getResultList(nums, resList, res, count, used);//回溯法求所有的排列组合
return resList;
}
//回溯法求所有的排列组合
void getResultList(int[] nums, List<List<Integer>> resList, List<Integer> res, int count, boolean[] used){
if(count == nums.length){//空格已填满
resList.add(new ArrayList<>(res));//注意:先对res当前的内容进行拷贝,再加入结果集(因为res一开始为空,其内容在回溯过程一直改变,最后也为空)
return;
}
for(int i = 0; i < nums.length; i++){//寻找数组nums[]中尚未使用过的数字
if(!used[i]){//尚未使用
res.add(nums[i]);//构建排列组合
used[i] = true;//已使用
getResultList(nums, resList, res, count + 1, used);//递归构建排列组合
res.remove(res.size() - 1);//撤销空格填入的数字
used[i] = false;//撤销标记数组used[]的对应标记
}
}
}
}