其实也算是蛮典型的回溯,利用递归每次向 temp
里添加一个数字,数字添加够以后再回来进行回溯,再向后添加新的解。
可以理解成一层一层的添加,每一层都是一个 for 循环。
每调用一层就进入一个 for 循环,相当于列出了所有解,然后挑选了我们需要的。其实本质上就是深度优先遍历 DFS
。
class Solution {
public List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
List<Integer> tempList = new ArrayList<>();
backtrace(list,tempList,nums);
return list;
}
private void backtrace(List<List<Integer>> list,List<Integer> tempList,int[] nums){
if(tempList.size() == nums.length){
list.add(new ArrayList<>(tempList));
}else{
for(int i =0;i<nums.length;i++){
if(tempList.contains(nums[i])) continue;
tempList.add(nums[i]);
backtrace(list,tempList,nums);
tempList.remove(tempList.size() - 1);
}
}
}
public static void main(String args[]) {
int[] nums= {1,2,3};
List<List<Integer>> ans=permute(nums);
System.out.println(ans);
}
}
class Solution(object):
def permute(self, nums):
list1 = []
tempList = []
self.backtrace(list1,tempList,nums)
return list1
def backtrace(self,list1,tempList,nums):
if(len(tempList) == len(nums)):
list1.append(list(tempList))
else:
for i in range(len(nums)):
if nums[i] in tempList:
continue
tempList.append(nums[i])
self.backtrace(list1,tempList,nums)
del tempList[len(tempList)-1]
假设有一个函数,可以实现题目的要求,即产生 nums 的所有的组合,并且加入到 all 数组中。不过它多了一个参数,begin,即只指定从 nums [ begin ] 开始的数字,前边的数字固定不变。
upset(int[] nums, int begin, List<List<Integer>> all)
如果有这样的函数,那么一切就都简单了。
如果 begin 等于 nums 的长度,那么就表示 begin 前的数字都不变,也就是全部数字不变,我们只需要把它加到 all 中就行了。
if (begin == nums.length) {
ArrayList<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < nums.length; i++) {
temp.add(nums[i]);
}
all.add(new ArrayList<Integer>(temp));
return;
}
如果是其它的情况,我们其实只需要用一个 for 循环,把每一个数字都放到 begin 一次,然后再变化后边的数字就够了,也就是调用 upset 函数,从 begin + 1 开始的所有组合。
for (int i = begin; i < nums.length; i++) {
swap(nums, i, begin);
upset(nums, begin + 1, all);
swap(nums, i, begin);
}
总体就是这样了。
public class permute2 {
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> all = new ArrayList<>();
//从下标 0 开始的所有组合
upset(nums, 0, all);
return all;
}
private static void upset(int[] nums, int begin, List<List<Integer>> all) {
if (begin == nums.length) {
ArrayList<Integer> temp = new ArrayList<Integer>();
for (int i = 0; i < nums.length; i++) {
temp.add(nums[i]);
}
all.add(new ArrayList<Integer>(temp));
return;
}
for (int i = begin; i < nums.length; i++) {
swap(nums, i, begin);
upset(nums, begin + 1, all);
swap(nums, i, begin);
}
}
private static void swap(int[] nums, int i, int begin) {
int temp = nums[i];
nums[i] = nums[begin];
nums[begin] = temp;
}
}