描述:
给定一个数字列表,返回其所有可能的排列。
样例:
样例 1:
输入:[1]
输出:
[
[1]
]
样例 2:
输入:[1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
代码:
public List<List<Integer>> permute(int[] nums) {
// write your code here
List<List<Integer>> list=new ArrayList<>();
if(nums==null){
return null;
}
if(nums.length==0){
list.add(new ArrayList<Integer>());
return list;
}
List<Integer> tmplist=new ArrayList<>();
DFS(list,tmplist,nums);
return list;
}
public void DFS(List<List<Integer>> list,List<Integer> tmplist,int[] nums){
if(tmplist.size()==nums.length){
list.add(new ArrayList<>(tmplist));
return;
}
for(int i=0;i<nums.length;i++){
if(tmplist.contains(nums[i])){
continue;
}
tmplist.add(nums[i]);
DFS(list,tmplist,nums);
tmplist.remove(tmplist.size()-1);
}
}
补充说明:
每次循环,取出一个元素添加的结果数组中,而对剩余的元素进行相同的全排列操作。终止条件:剩余的元素为1。
如[1,2,3,4]的全排列,可以看成是将1或2或3或4(for)放在固定位置,[2,3,4],[1,3,4],[1,2,4],[1,2,3]的全排列,以此类推,[2,3,4]的全排列,可以看成是将2或3或4放在固定位置,[3,4],[2,4],[2,3]的全排列,直到数组中仅有一个元素为止。
代码2:(这个较好理解,visited[]是标志位,标记是否被访问过)
public List<List<Integer>> permute(int[] nums) {
// write your code here
List<List<Integer>> res=new ArrayList<>();
boolean[] visited=new boolean[nums.length];//标志位,标记是否被访问过
if(nums==null)
return res;
if(nums.length==0){
res.add(new ArrayList<Integer>());
return res;
}
dfs(nums,new ArrayList<Integer>(),res,visited,0);
return res;
}
private void dfs(int[] nums,List<Integer> list,List<List<Integer>> res,boolean[] visited,int index){
if(list.size()==nums.length){
res.add(new ArrayList<Integer>(list));
return;
}
for(int i=0;i<nums.length;i++){
if(!visited[i]){
list.add(nums[i]);
visited[i]=true;
dfs(nums,list,res,visited,i+1);
list.remove(list.size()-1);
visited[i]=false;
}
}
}