【LeetCode】46. Permutations()中等难度

本文介绍了两种使用回溯法和递归实现整数数组全排列的方法。第一种方法通过逐层添加数字进行回溯,本质上是深度优先搜索;第二种方法通过固定前部分数字并递归处理后部分,实现数组的不同组合。这两种方法都能有效地找出给定数组的所有可能排列组合。
摘要由CSDN通过智能技术生成

在这里插入图片描述

方法一 回溯法

啊 一看完题目就想到回溯,利⽤递归每次向 temp ⾥添加⼀个数字,数字添加够以后再回来进⾏回溯,再向后添加新的解。

可以理解成⼀层⼀层的添加,每⼀层都是⼀个 for 循环
在这里插入图片描述
每调⽤⼀层就进⼊⼀个 for 循环,相当于列出了所有解,然后挑选了我们需要的。其实本质上就是深度优先遍历 DFS。

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        backtrack(res, nums, new ArrayList<>());
        return res;
    }
    public void backtrack(List<List<Integer>> res, int[] nums, List<Integer> temp){
        if(temp.size() == nums.length){
            res.add(new ArrayList<>(temp));
            return;
        }else{
            for(int i = 0; i < nums.length; i++){
                if(temp.contains(nums[i])) continue;
                temp.add(nums[i]);
                backtrack(res, nums, temp);
                temp.remove(temp.size() - 1);
            }
        }
    }
}

方法二 递归

假设有⼀个函数,可以实现题⽬的要求,即产⽣ nums 的所有的组合,并且加⼊到 res 数组中。不过它多了⼀个参数,index,即只指定从 nums [ index ] 开始的数字,前边的数字固定不变。

upset(List<List<Integer>> res, int[] nums, int index)

如果有这样的函数,那么⼀切就都简单了。

如果 index 等于 nums 的⻓度,那么就表示 index 前的数字都不变,也就是全部数字不变,我们只需要把它加到 res 中就⾏了。

如果是其它的情况,只需要⽤⼀个 for 循环,把每⼀个数字都放到 begin ⼀次,然后再变化后边的数字就够了,也就是调⽤ upset 函数,从 index + 1 开始的所有组合。

class Solution {
    public List<List<Integer>> permute(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        upset(res, nums, 0);
        return res;
    }
    public void upset(List<List<Integer>> res, int[] nums, int index){
        if(index == nums.length){
            ArrayList<Integer> temp = new ArrayList<Integer>();
            for(int i = 0; i < nums.length; i++){
                temp.add(nums[i]);
            }
            res.add(new ArrayList<>(temp));
            return;
        }
        for(int i = index; i < nums.length; i++){
            swap(nums, i, index);
            upset(res, nums, index + 1);
            swap(nums, i, index);
        }
    }
    public void swap(int[] nums, int i, int index){
        int temp = nums[i];
        nums[i] = nums[index];
        nums[index] = temp;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玳宸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值