全排列
刚遇到这道题,对回溯算法不熟悉的我,真的太难了。虽然对深度遍历还是有一点理解的。
做完这道题,我感觉对回溯算法有了更好的理解
想看完整代码,可以直接拉到最后
下面我是逐个代码块分析
下面的这顿代码是主程序入口,为了模拟用。
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
List<List<Integer>> permute = permute(arr);
System.out.println(permute.toString());
}
首先leetcode给出的方法返回值是 List<List>,所以,我们就需要弄个这样的list出来,也就是存储数组中的数组
List inlist = new ArrayList<>(); 存储数组
boolean[] user = new boolean[nums.length]; 用来标记数组中某个数,有没有用过
dfs(nums,list,0,inlist,user); 深度遍历。从0开始,相当于 空。因为下面的分支是1 、2、3
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
List<Integer> inlist = new ArrayList<>();
boolean[] user = new boolean[nums.length];
dfs(nums,list,0,inlist,user);
return list;
}
下面就是代码的核心了
当数组的长度为3,则放进去,存储起来,然后回溯一下。改变的是k值
if (nums.length==k){
list.add(new ArrayList<>(inlist));
return;
}
核心思想:
先进行
for循环,遍历数组里面的元素,第一个标记为true,然后添加进数组,进行dfs,不满足nums.length==k的条件,
for循环数组三个数字,因为第二个为true了,所以i变为1,进行dfs,不满足nums.length==k的条件,
for循环数组三个数字,因为第三个为true了,所以i变为2, 第三个标记为true, 存进去。进行dfs,nums.length==k的条件,存进去。
retrun 返回。k=2.
user[i]=false;
inlist.remove(inlist.size()-1);i=2,所以退出
然后执行了这两步,最后
退出第三个次循环 , 跳出dfs,各项数值回到第二次循环
user[i]=false;
inlist.remove(inlist.size()-1);
这时候,inlist只有1了,只有 user[1]为true,后面进行第二次循环,进行了i++之后,变成了i=2,所以,进去的是3
inlist=[1,3],后面,又跳出第二次循环,回到第一次循环。此时第一个循环是数值为1,3下标对应为true,所以循环,只有2进去。
形成数组inlist=[1,2,3].
后面以此类推。
public static void dfs(int[] nums, List<List<Integer>> list,int k,List<Integer> inlist, boolean[] user){
if (nums.length==k){
list.add(new ArrayList<>(inlist));
return;
}
for (int i=0;i<nums.length;i++){
if (!user[i]){
user[i]=true;
inlist.add(nums[i]);
dfs(nums,list,k+1,inlist,user);
user[i]=false;
inlist.remove(inlist.size()-1);
}
}
完整代码
package com.wu.leetcode;
import java.util.ArrayList;
import java.util.List;
//输入:nums = [1,2,3]
// 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
public class 全排列 {
public static void main(String[] args) {
int[] arr = new int[]{1,2,3};
List<List<Integer>> permute = permute(arr);
System.out.println(permute.toString());
}
public static List<List<Integer>> permute(int[] nums) {
List<List<Integer>> list = new ArrayList<>();
List<Integer> inlist = new ArrayList<>();
boolean[] user = new boolean[nums.length];
dfs(nums,list,0,inlist,user);
return list;
}
public static void dfs(int[] nums, List<List<Integer>> list,int k,List<Integer> inlist, boolean[] user){
if (nums.length==k){
list.add(new ArrayList<>(inlist));
return;
}
for (int i=0;i<nums.length;i++){
if (!user[i]){
user[i]=true;
inlist.add(nums[i]);
dfs(nums,list,k+1,inlist,user);
user[i]=false;
inlist.remove(inlist.size()-1);
}
}
}
}