LeetCode刷题日志-46.全排列

news/2024/7/20 20:25:31 标签: leetcode, 算法, 深度优先, 回溯算法

在这里插入图片描述
跟77题组合一样,在这里又遇到同样的问题,如果使用暴力解法,nums大小不同,使用的循环嵌套的层数也不同。那么这时候我们就需要使用暴力的解法。
我们看以下代码,如果nums = [1,2,3]会输出什么?

class Solution {

    List<List<Integer>> result = new ArrayList<>(); //记录最终结果
    List<Integer> path = new LinkedList<>();//记录单个组合

    public List<List<Integer>> permute(int[] nums) {
        traceBacking(nums);
        return result;
    }
    public void traceBacking(int[] nums){
        if(path.size() == nums.length)//若满足条件,终止
        {
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0; i < nums.length; i++){//
            path.add(nums[i]);
            traceBacking(nums);
            path.removeLast();
            }
        }
    }
}

以上代码会输出以下信息:
[[1,1,1],[1,1,2],[1,1,3],[1,2,1],[1,2,2],[1,2,3],[1,3,1],[1,3,2],[1,3,3],[2,1,1],[2,1,2],[2,1,3],[2,2,1],[2,2,2],[2,2,3],[2,3,1],[2,3,2],[2,3,3],[3,1,1],[3,1,2],[3,1,3],[3,2,1],[3,2,2],[3,2,3],[3,3,1],[3,3,2],[3,3,3]]
发现他每个元素都会重复出现,为什么会这样?

for(int i = 0; i < nums.length; i++){//
            path.add(nums[i]);
            traceBacking(nums);
            path.removeLast();
            }

因为上面这段代码在每次递归都会从nums[0]开始,所以会出现重复。
现在思考如何去重
我们可以设置一个boolean数组,数组大小等于nums1的大小,用于记录nums中的元素有没有被使用,如果被使用,我们在选择添加元素时可以不添加,那么就不会有重复元素出现,得到的最终结果也就是全排列。于是有以下代码:
在这里插入图片描述

class Solution {

    List<List<Integer>> result = new ArrayList<>(); //记录最终结果
    List<Integer> path = new LinkedList<>();//记录单个组合

    public List<List<Integer>> permute(int[] nums) {
        boolean[] used = new boolean[nums.length];//记录是否已经使用

        for(int i = 0; i<nums.length; i++){
            used[i] = false;
        }
        traceBacking(nums,used);
        return result;
    }
    public void traceBacking(int[] nums,boolean[] used){
        if(path.size() == nums.length)
        {
            result.add(new ArrayList<>(path));
            return;
        }
        for(int i = 0; i < nums.length; i++){
        if (!used[i]) {//如果没有使用
            path.add(nums[i]);//就添加该元素
            used[i] = true;//标记为已经使用
            traceBacking(nums,used);//递归
            used[i] = false;//记得递归返回后,该元素为未使用,因为返回了说明已经添加进结果集,那么就要进行新一轮递归了,元素当然回归未使用状态
            path.removeLast();
            }
        }
    }
}

其实在纸上模拟几遍回溯执行的过程就可以发现,他其实是在模拟嵌套循环:

 if(path.size() == nums.length)
        {
            result.add(new ArrayList<>(path));
            return;
        }

这个递归返回的条件就是循环的嵌套层数

if (!used[i]) {//如果没有使用
            path.add(nums[i]);//就添加该元素
            used[i] = true;//标记为已经使用
            traceBacking(nums,used);//递归
            used[i] = false;//记得递归返回后,该元素为未使用,因为返回了说明已经添加进结果集,那么就要进行新一轮递归了,元素当然回归未使用状态
            path.removeLast();
            }

这里就是从最内层开始遍历。

在这里插入图片描述


http://www.niftyadmin.cn/n/5420547.html

相关文章

Studio One 6 Pro for Mac/Win:音乐创作与编辑的巅峰之作,引领你的音乐梦想启航

在浩瀚的音乐海洋中&#xff0c;每一位音乐创作者都渴望拥有一款能够激发灵感、助力创作的神器。今天&#xff0c;我们为大家隆重推荐Studio One 6 Pro——这款专为音乐创作与编辑而设计的巅峰之作&#xff0c;它将带你走进一个全新的音乐世界&#xff0c;让你的音乐梦想启航。…

Pytorch学习 day06(torchvision中的datasets、dataloader)

torchvision的datasets 使用torchvision提供的数据集API&#xff0c;比较方便&#xff0c;如果在pycharm中下载很慢&#xff0c;可以URL链接到迅雷中进行下载&#xff08;有些URL链接在源码里&#xff09;用来告诉程序&#xff0c;数据集存储的位置&#xff0c;共有多少样本等…

NLP:spacy库安装与zh_core_web_sm配置

到公司来第一个项目竟然是偏文本信息抽取与结构化的&#xff0c;&#xff08;也太高看我了┭┮﹏┭┮&#xff09; 反正给机会了就上吧&#xff0c;我就一臭实习的&#xff0c;怕个啥。配置了两天的环境&#xff0c;也踩了不少坑&#xff0c;我把我的经历给大家分享一下&#…

【Python3】观察者模式

观察者模式&#xff08;Observer Pattern&#xff09;是一种常见的设计模式&#xff0c;用于定义对象之间的一对多依赖关系&#xff0c;使得一个对象的状态改变能够通知所有依赖于它的对象并自动更新。 在观察者模式中&#xff0c;有两个核心角色&#xff1a; Subject&#xf…

(3).o文件

然后我们把俩文件都编译为.o文件 .o文件是二进制&#xff0c;需要用readelf工具查看 我们首先看main.o .o文件是没有入口地址的&#xff0c;也没有program headers&#xff0c;这是由连接器给出的 .strtab .strtab 是 ELF 文件中的一个特殊节(section)&#xff0c;用于存储字…

力扣--动态规划/回溯算法131.分割回文串

思路分析&#xff1a; 动态规划 (DP)&#xff1a; 使用动态规划数组 dp&#xff0c;其中 dp[i][j] 表示从字符串 s[i] 到 s[j] 是否为回文子串。预处理动态规划数组&#xff1a; 从字符串末尾开始&#xff0c;遍历每个字符组合&#xff0c;判断是否为回文子串&#xff0c;填充…

java-新手笔记-(Lambda表达式, 匿名内部类,作用域,闭包)

Lambda表达式 定义:可以看作是一种没有名称&#xff08;即匿名&#xff09;的函数。Lambda表达式主要用于表示那些只有一个抽象方法的接口&#xff08;即函数式接口&#xff09;的实例. 这边可以用接口定义抽象的方法,再用lambda继续完善方法,注意的是 接口是只支持单一函数l…

UDP-创建群聊

服务器 #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h>#define send_port "8888" #define send_ip "1…