LeetCode刷题之T46全排列(中等)

大家好,这次我们讲解的题目是LeetCode刷题之T46全排列(中等),话不多说,上题:
在这里插入图片描述
解题思路:
这道题的要用到回溯算法,而解决每一个回溯问题,实际上就是一个决策树的问题,不明白的话,我举个例子:
我们可以先看图:
在这里插入图片描述
由图我们看出:[1,2,3]使我们的一组解,跟着我来分析:
1:首先选择的1。
2:接着可以选1,2,3,我们先选1,但是1选择过了(nums不重复的数组),所以我们只能够往回走,即1->1为叉叉
3:接着我们可以选1->2
4:我们选择了1->2,接着我们可以选1,2,3,如果我们选择1,就是1->2->1,但是1选过了,就要往回走,看看能不能1->2->2,但是2选过了,我们看能不能选择3,1->2->3,可以。
经过上面的分析,什么叫回溯就出来了,其实本质就是一个决策树,树的分支代表你的选择情况(决策),就是我们往回走,回到上一步。
那么我们怎么设计算法呢?
我还是拿上面那张图
在这里插入图片描述
算法设计思路:
1:定义一个track,代表路径,用track来记录我们的路径,当track的程度等于nums的长度,就说明这个是其中的一种排列情况。
2:因为nums数组里的数不可重复,所以track里面出现过的数,就代表我们不需要往分支在track里面存在过的数,比如上如,1->1,行不通,因为track[1]里面存在1,上图简易的用三元运算表示了一下,存在,那么回溯,不存在那么添加进track,说明我们当前是最终的一个排列的组成部分。
3:根据上述说明结合上图,就能得到我们算法的设计思路,这个只是图只是其中一部分,所以我们采用递归的方法。
接下来上代码:

class Solution {
    //返回结果
    List<List<Integer>> res = new  LinkedList<List<Integer>>(); //表示结果

    public List<List<Integer>> permute(int[] nums) {
        LinkedList<Integer> track=new LinkedList<>(); //表示当前的路径
        backtrack(nums,track);  //数组和当前的走过的路径放进去 递归函数
        return res;
    }

    // 递归函数
    public void backtrack(int[] nums,LinkedList<Integer> track){
        //递归的结束条件,track的长度和数组长度相等,则说明当前track为一次排列
        if(track.size()==nums.length){
            res.add(track);
            return;
        }

        //判断条当前决策是否能添加进track 
        for(int i=0;i<nums.length;i++){
            if(track.contains(nums[i])){ //因为数组无重复数字,说明此数字已经用过,此路不通 
                continue;  
            }
            track.add(nums[i]); //添加进当前的路径
            backtrack(nums,track);//保存当前的看路径继续递归
            track.removeLast();  //取消track的最后一个,也就是返回上一次的决策。
        }
    }
}

这道题难度较高,需要仔细结合图片以及理解递归,决策,回溯的概念就能更好的理解!
在这里插入图片描述
哈哈有点惨不忍睹!如果有更好的想法欢迎在下方留言!希望能帮助到大家!谢谢!

猜你喜欢

转载自blog.csdn.net/Pzzzz_wwy/article/details/105759196