Leetcode笔记----46.全排列

给定一个 没有重复 数字的序列,返回其所有可能的全排列。

这道题很好理解,如果自己在纸上写的话也很好写:比如把123写在纸上,然后1放在最前面,然后是2,3,然后把3拿掉,2拿掉,放3和2…这样反复地先写一个排列,拿掉几个数字再组成另一个排列,最终得到所有的排列情况,在算法中,这叫做“回溯法”。
所谓回溯法,顾名思义就是在搜索过程中不停回溯,这样一看就和深度优先搜索有着千丝万缕的联系,而这道题目中的回溯法其实就是模拟了在纸上反复试错的过程:通过递归函数,其参数中包括当前深度/数组/结果数组/当前路径/数组长度以及一个存储访问情况的数组。递归分为两部分,一部分是当前深度与数组长度相等时,则在结果中加入当前路径并return,然后进行回溯:体现在代码中是将当前元素的visited值变为0,并将其从路径中删除。

public List<List<Integer>> permute(int[] nums) {
       int len = nums.length;
       List<List<Integer>> res = new ArrayList<List<Integer>>();
       int []visited = new int[len];
       List<Integer> path = new ArrayList<>();
       for(int i = 0 ;i < len;i++){
           visited[i] = 0;
       }
       dfs(res,0,len,nums,visited,path);
       return res;
    } 
    void dfs(List<List<Integer>> res,int depth,int len,int[]nums,int[]visited,List<Integer>path){
         if(depth == len){
            res.add(new ArrayList<>(path));
            return ;
         }
         for(int i = 0;i<len;i++){
            if(visited[i]!=1){
                visited[i] = 1;
                path.add(nums[i]);
                dfs(res,depth+1,len,nums,visited,path);
                visited[i] = 0;
                path.remove(path.size()-1);
            }
         }
    }

代码中值得注意的点为 res.add(new ArrayList<>(path));如果不这么写的话,res最后会由几个空列表组成,这是因为java的传递机制,res.add(path)表示将path指向的列表变量传递给res,但path是一直在变的对象,且最终会变为空,因此每次添加值的时候需要给当前path进行一次拷贝,相当于进行一次快照并存储。
另外,for循环内的执行和递归顺序也需要多理解,虽然自己画图很好懂,但是体现在代码中的执行顺序就要慢慢想了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值