DFS与回溯专题:全排列

本文介绍了使用DFS(深度优先搜索)解决全排列问题的Java代码实现,包括基本的递归方法和利用数组标记元素状态的优化版本,以及讨论了利用`list.contains()`方法的替代方案。
摘要由CSDN通过智能技术生成

    DFS与回溯专题:全排列

题目链接: 46.全排列

题目描述

在这里插入图片描述

代码思路

回溯问题中的全排列,相对比组合、子集等问题,其元素可以颠倒顺序,所以在for循环中每层都是从头开始,无需标记更新起始位置

代码纯享版

class Solution {

    public List<List<Integer>> list_all = new ArrayList();
    public List<Integer> list = new ArrayList();
    public int[] res;

    public List<List<Integer>> permute(int[] nums) {
        res = new int[nums.length];
        backtrack(nums);
        return list_all;
    }

    void backtrack(int[] nums){

        if(list.size() == nums.length){
            list_all.add(new ArrayList(list));
        }

        for(int i = 0; i < nums.length; i++){
            if(res[i] == 1){
                continue;
            }
            list.add(nums[i]);
            res[i] = 1;
            backtrack(nums);
            res[i] = 0;
            list.remove(list.size() - 1);
        }
    }
}

代码逐行解析版

class Solution {

    public List<List<Integer>> list_all = new ArrayList();
    public List<Integer> list = new ArrayList();
    public int[] res;

    public List<List<Integer>> permute(int[] nums) {
        res = new int[nums.length]; //数组res用来判断对应位置的数是否用过:0为没用,1为用过
        backtrack(nums);
        return list_all;
    }

    void backtrack(int[] nums){

        if(list.size() == nums.length){ //当列表list的长度与数组nums长度相同时,说明已经完成一次全排列
            list_all.add(new ArrayList(list)); //将list添加到list_all
        }

        for(int i = 0; i < nums.length; i++){
            if(res[i] == 1){ //如果该数字已使用过,则直接退出本次循环
                continue;
            }
            list.add(nums[i]); //否则将该数字添加到list列表中
            res[i] = 1; //将该数字标记为已使用过
            backtrack(nums); //递归到下一个位置的排列
            //将列表list的最后一个数字去掉,同时还原标记
            res[i] = 0; 
            list.remove(list.size() - 1);
        }
    }
}

其他解法

也可以利用list.contains()方法来判断是否被使用,但这种方式会耗费较多时间。所以最好用前面的方法,已空间换时间

class Solution {

    public List<List<Integer>> list_all = new ArrayList();
    public List<Integer> list = new ArrayList();

    public List<List<Integer>> permute(int[] nums) {
        backtrack(nums);
        return list_all;
    }

    void backtrack(int[] nums){

        if(list.size() == nums.length){
            list_all.add(new ArrayList(list));
        }

        for(int i = 0; i < nums.length; i++){
            if(list.contains(nums[i])){
                continue;
            }
            list.add(nums[i]);
            backtrack(nums);
            list.remove(list.size() - 1);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值