LeetCode 回溯专题 46 全排列 题解

题目详情

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

输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

该题是一到比较简单而且经典的回溯题,或者说是排列组合穷举题,这种题只要回溯(dfs+删除操作)即可完成,写本文的目的在于,一是记录下回溯的一般写法,二是提醒自己关于java中的引用一定要注意。

题目分析

对于回溯问题的一般思路就是:

def backtrack(路径,选择列表)if满足条件:
          添加到最终结果
          return
      for 选择 in 选择列表:
             做选择
             backtrack(路径,选择列表)
             撤销选择

(这个是我在LeetCode评论区看来的,觉得挺好,@Teki)
基本就是这个思路就可以完成代码的书写。
我这里的代码写的稍稍有些冗余,其实可以不用标记数组,直接用List的contains方法即可,(这里mark一下,以后就用这个),因为平时java使用的还是有些少,比较生疏。
贴上代码:

//有思路了,就是建立一个marked数组,记录标记情况,然后for循环,跳过标记的,然后一直往下搜索就行如
    //可以判断一下数组的和是否等于长度来判断是否完了
    //总体还是很简单的
    public List<List<Integer>> permute(int[] nums) {
    
    
        List<List<Integer>> results = new LinkedList<>();
        if(nums==null||nums.length==0)
            return results;

        for(int i=0;i<nums.length;i++)
        {
    
    
            int[] marked = new int[nums.length];
            backtrack(nums,i,marked,new LinkedList<Integer>(),results,0);
        }

        return results;
    }
    public void backtrack(int[] nums, int index, int[] marked, LinkedList<Integer> result, List<List<Integer>> results,int count){
    
    
        //count用于判断当前是否满了
        if(count==nums.length-1&&marked[index]==0){
    
    
            result.add(nums[index]);
            // System.out.println(result);
            results.add((List<Integer>)result.clone());//这里需要进行一个拷贝,不然里面存的都是一个变量,最后值都为0了
            result.remove(result.size()-1);
            return;
        }

        //判断当前索引是否被遍历过
        if(marked[index]==1)
            return;
        //如果都没有,则说明可以遍历
        //先把自己放进result中去
        result.add(nums[index]);
        marked[index]=1;
        count++;
        //再从头开始遍历
        for(int j=0;j<nums.length;j++)
            backtrack(nums,j,marked,result,results,count);
        //最终把自己删掉
//        System.out.println(nums[index]);
        result.remove(result.size()-1);
        marked[index]=0;
        count--;
    }

这里,在results.add((List<Integer>)result.clone());这一行,我一开始写的是results.add(result),结果就导致了最后输出的结果都是空(因为回溯),想了一会儿才想起来,这里不是基本类型,而是引用类型,所以必须要进行一次拷贝,然后发现List无法用clone,查了一会儿才发现,哦原来要用LinkedList或者ArrayList才可以,然后再需要一次强制类型转换。

猜你喜欢

转载自blog.csdn.net/qq_34687559/article/details/109090742
今日推荐