方法一(采用交换的方法):
public class L46 { public void backtrack(int n, ArrayList<Integer> nums, List<List<Integer>> output,int first){ if(first==n){ output.add(new ArrayList<Integer>(nums)); } for(int i=first;i<n;i++){ Collections.swap(nums,first,i); backtrack(n,nums,output,first+1); Collections.swap(nums,first,i); } } public List<List<Integer>> permute(int[] nums){ List<List<Integer>> output=new LinkedList<>(); ArrayList<Integer> nums_lst=new ArrayList<>(); for(int num:nums){ nums_lst.add(num); } int n=nums.length; backtrack(n,nums_lst,output,0); return output; } }
第二种(太慢了):
class Solution { public List<List<Integer>> permute(int[] nums){ int n=nums.length; List<List<Integer>> output=new ArrayList<>(factorial(n)); if(n==0) return output; boolean[] used = new boolean[n]; List<Integer> path = new ArrayList<>(); dfs(nums,n,0,path,used,output); return output; } private int factorial(int n){ int res=1; for(int i=2;i<=n;i++){ res *=i; } return res; } private void dfs(int[] nums,int len,int depth,List<Integer> path,boolean[] used,List<List<Integer>> res){ if(depth==len) { res.add(path); return; } for(int i=0;i<len;i++){ if (!used[i]) { // 1、每一次尝试都创建新的变量表示当前的"状态" List<Integer> newPath = new ArrayList<>(path); newPath.add(nums[i]); boolean[] newUsed = new boolean[len]; System.arraycopy(used, 0, newUsed, 0, len); newUsed[i] = true; dfs(nums, len, depth + 1, newPath, newUsed, res); // 2、无需回溯 } } } }
第三种(目前最快的):采用回溯的方法
public class L46_2 { List<List<Integer>> ans=new ArrayList<>(); boolean[] visited; public List<List<Integer>> permute(int[] nums) { visited=new boolean[nums.length]; helper(nums,new LinkedList<>()); return ans; } void helper(int[] nums,LinkedList<Integer> list){ if(list.size()==nums.length){ ans.add(new ArrayList<>(list));
//path 这个变量所指向的对象在递归的过程中只有一份,深度优先遍历完成以后,因为回到了根结点
//(因为我们之前说了,从深层结点回到浅层结点的时候,需要撤销之前的选择),因此 path 这个变量回到根结点以后都为空。
//在 Java 中,因为都是值传递,对象类型变量在传参的过程中,复制的都是变量的地址。
//这些地址被添加到 res 变量,但实际上指向的是同一块内存地址,因此我们会看到 6 个空的列表对象。
return; } for(int i=0;i<nums.length;i++){ if(!visited[i]){ visited[i]=true; list.add(nums[i]); helper(nums,list); list.removeLast(); visited[i]=false; } } } }