(回溯) LeetCode 47. 全排列||

news2024/11/26 0:44:09

原题链接

建议先练习:全排列|

一. 题目描述

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

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

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

二. 解题思路

这个题目和之前的全排列一相似,唯一不相同的地方就是在上一题中明确规定数组中不存在重复元素,但是这个里面存在重复的元素,所以我们自然而然的可以想到去重,那该怎么去重呢,原理很简单,与之前组合一和组合二的去重方法相同,建议大家可以先去练习一下。

老套路:递归三件套!!但是这个在做之前得将原数组nums 排序,保证重复的元素在一起,这样才方便进行去重操作。

1. 确定递归条件:和之前全排列一的思路相同,只需要一个nums 原数组和 used 数组记录path 已经加入的元素。

2. 确定递归的终止条件:由于是递归,所以也很简单,只需要path.size() == nums.size() 的时候,将结果收集到res 中再return 即可。

3. 单层递归原则:首先我们得进行去重操作:如下图所示,当第一层中选取了第一个1的时候,回溯之后就没必要选取第二个1了,因为同一层选取相同的元素势必会出现相同的结果,所以直接剪枝即可,但是怎么剪枝呢?(1)判断当前元素和前一个元素是否相同,即 i > 0 && nums[i] == nums[i - 1]。(2) 判断当前元素是否是同一层相同元素回溯得来,即 used[i - 1] == false,因为在回溯之前会选取 nums[i - 1] ,这时候会将used[i - 1] 赋值为 true, 在回溯结束之后,会将 used[i - 1] 重新赋值为 false,这就是在树层上去重的一个操作。其次,在进行树层上的剪枝之后,需要进行树枝上的剪枝,即判断 used[i] 时候为 true ,如果为true ,说明在path 中已经选取了该元素,continue 即可。最后就是熟悉的递归操作,将used[i] 赋值为 true,并在 path 中添加 nums[i] ,然后进行递归,递归结束后回溯即可。

写了一大堆,可能可读性不是很好,希望大家可以看懂。

话不多说!!!上代码!!

三. 代码

class Solution {
public:
    vector<vector<int>> res;
    vector<int> path;
    void back(vector<int>& nums, vector<bool> used){
        if(path.size() == nums.size()) {
            res.push_back(path);
            return;
        }
        for(int i = 0; i < nums.size(); i++){
            if(i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){        
                continue;
            }
            if(used[i]) continue;
            used[i] = true;
            path.push_back(nums[i]);
            back(nums, used);
            used[i] = false;
            path.pop_back();
        }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        vector<bool> used(nums.size(), false);
        back(nums, used);
        return res;
    }
};

四. 总结

本题还是属于回溯里面比较进阶的题目吧,建议大家练习,但是一定要懂得每一步的作用以及结果,写代码一定要勤思考,多思考就能印象深刻。加油!!我们共勉!

时间复杂度:O(n! * n)

空间复杂度:O(n)

喜欢的话给个关注吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035694.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE初阶】线程池

目录 &#x1f4d5; 引言 &#x1f333; 概念 &#x1f340;ThreadPoolExecutor 类 &#x1f6a9; int corePoolSize与int maximumPoolSize&#xff1a; &#x1f6a9; long keepAliveTime与TimeUnit nuit&#xff1a; &#x1f6a9; BlockingQueue workQueue&#xff1a…

C# 序列化与反序列化指南:将对象数据写入/读取到XML文件

文章目录 1. XML 文件的基本概念以及为何使用 XML 文件进行数据序列化2. C# 中的 XML 文件序列化使用 XmlSerializer 类进行操作的详细步骤3. 创建一个自定义对象并序列化对象数据到 XML 文件的示例代码4. 读取 XML 文件并反序列化&#xff08;将 XML 数据转换为对象数据&#…

【Redis】Redis 初探:特性、应用场景与高并发架构演进之路

目录 初识 Redis关于 Redis服务端高并发分布式结构演进之路概述常⻅概念基本概念应⽤&#xff08;Application&#xff09;/ 系统&#xff08;System&#xff09;模块&#xff08;Module&#xff09;/ 组件&#xff08;Component&#xff09;分布式&#xff08;Distributed&…

LVS 、DR模式

lvs --环境 主机名IP地址功能web1192.168.1.17 rs web2192.168.1.18realservenat 内&#xff1a;192.168.1.16 外&#xff1a;192.168.1.102 directorserver,ntpdns192.168.1.12dns --web1、web2 yum -y install nginxecho "xx" > /usr/share/nginx/html/index.…

系统编程 day10 进程2

进程创建之后&#xff1a; 1.任务-----子进程与父进程干的活差不多 2.父进程创建出子进程之后&#xff0c;子进程做的与父进程完全不同 shell程序-----bash----- 以上为进程运行的过程中&#xff0c;典型的两种应用场景 能够改变子进程的执行效果的函数是exec函数族 l和v&a…

【2024】k8s集群 图文详细 部署安装使用(两万字)

目录&#x1f4bb; 一、前言二、下载依赖配置环境1、配置系统环境1.1、配置桥接网络1.1.1、parallels desktop配置1.1.2、VMware配置 1.2、配置root用户登陆 2、环境配置安装下载2.1、安装ipset和ipvsadm2.2、关闭SWAP分区 3、配置Containerd容器3.1、下载安装Containerd3.2、创…

数据结构之线性表(单链表的实现)

目录 一、单链表的原理 二、单链表的实现 1.单链表的定义 2.单链表的初始化 3.清空单链表 4.单链表是否为空 5.单链表的长度 6.获取指定位置 i 的元素 7.获取指定元素 e 的位置 8.向链表中插入指定位置的元素 9.向链表中删除指定位置的元素 10.遍历链表中的元素 …

zdppy+vue3+onlyoffice开发文档管理系统实战 20240813登录功能中Python生成验证码校验的研究

遗留的问题 1、登录功能 5、设计登录的接口 6、前后端联调&#xff0c;实现登录功能 7、要记录登录的Token和用户名&#xff0c;跳转到首页 2、注册功能 3、用户管理 4、角色管理 5、权限管理 6、分享功能 tb_user拆成基本信息和详细信息两张表。 6、前后端联调&#xff0c…

设计模式-标识映射(Identity Map)

概念 通过在映射中保存每个已经加载的对象&#xff0c;确保每个对象只加载一次。当要访问对象的时候&#xff0c;通过映射来查找他们。 从数据库加载对象时&#xff0c;对象与其映射的一致性、重复加载&#xff0c;这些都是需要得到保证的。 标识映射记录在一个业务事务中从数…

2024年中国AI大模型场景应用趋势解读

引言 >> 近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;AI大模型逐渐成为推动各行业数字化转型的重要驱动力。本文从行业现状、应用痛点、发展趋势以及投资机会等方面进行详细解读&#xff0c;探讨AI大模型在未来的广泛应用前景。 一、AI大模型行业应用现状…

【LLM大模型】Llama3.1 部署本地知识库应用

一. 环境介绍 高性能应用服务 HAI 拥有丰富的预装应用&#xff0c;可以将开源社区的前沿模型快速转化为您专有的部署实践&#xff0c;一键拉起&#xff0c;即开即用。现已支持在HAI购买页的社区应用中&#xff0c;找到Llama 3.1等应用的入口&#xff0c;简单选型后&#xff0c…

【MySQL 05】数据类型

&#x1f308; 一、数据类型的作用 如果向 MySQL 特定的类型中插入不合法的数据&#xff0c;MySQL 一般会将本次操作直接拦截。反过来讲&#xff0c;能被成功插入到 MySQL 中的数据一定合法。在 MySQL 中&#xff0c;数据类型本身也是一种约束&#xff0c;这种约束约束的是使用…

一篇文章教会你如何使用Haproxy,内含大量实战案例

1. Haproxy 介绍 HAProxy是法国开发者 威利塔罗&#xff08;Willy Tarreau&#xff09; 使用C语言编写的自由及开放源代码软件&#xff0c;是一款具备高并发&#xff08;万级以上&#xff09;、高性能的TCP和HTTP应用程序代理. HAProxy运行在当前的硬件上&#xff0c;可以支持…

Ubuntu20源码安装Moveit 与 OMPL

文章目录 一、源码安装OMPL1.1 先检查是否安装二进制ompl1.2 若已经提前安装二进制&#xff0c;需要先行卸载1.3 OMPL官网安装教程 一、源码安装OMPL 1.1 先检查是否安装二进制ompl //进入到如下目录下 cd /opt/ros/noetic/// 查找 find ./ -name "libompl*" find .…

Linux用户ID和组ID

在 Linux 系统中&#xff0c;用户和组 ID 用于识别进程和文件的访问权限。每个进程都有与之关联的实际用户 ID、实际组 ID、有效用户 ID、有效组 ID 以及附属组 ID。 实际用户 ID (Real User ID, UID) 定义&#xff1a;实际用户 ID 是启动进程的用户的 ID。作用&#xff1a;标…

文件中找TopK问题 的详细讲解

一&#xff1a;问题&#xff1a; 从一个包含10000整数的文件中找出最大的前10个数。 二&#xff1a;方法&#xff1a; 1&#xff1a;先直接拿文件的前10个数&#xff0c;建造一个小堆 2&#xff1a;再依次读取文件中&#xff0c;剩下的数&#xff0c;比堆顶大&#xff0c;则…

【MATLAB源码-第246期】基于matlab的秃鹰搜索优化算法(BES)机器人栅格路径规划,输出做短路径图和适应度曲线

操作环境&#xff1a; MATLAB 2022a 1、算法描述 秃鹰搜索优化算法&#xff08;Bald Eagle Search, BES&#xff09;是一种新颖的群体智能优化算法&#xff0c;受自然界中秃鹰猎食行为的启发而设计。与其他群体智能算法类似&#xff0c;BES试图通过模拟自然界的某些行为来解…

SSM药房管理系统---附源码18275

目录 摘要 1 绪论 1.1 研究目的意义 1.2国内外研究现状 2 药房管理系统分析 2.1 可行性分析 2.1.1 技术可行性分析 2.1.2经济可行性分析 2.1.3社会可行性分析 2.1.4操作可行性分析 2.2 系统流程分析 2.2.1数据新增流程 2.2.2数据删除流程 2.3 药房管理系统 功能分…

idea过滤器 过滤所有页面除了登录页面 !(包括白名单简洁概括)

1、创建过滤器包&#xff0c;创建LoginFilter类 2.在LoginFilter类中写过滤代码 //白名单List<String> whitelist Arrays.asList("/login.jsp");//用来存放配置文件中Action节点的属性List<Action> actionList new ArrayList<>(); public void …

这些坑都没有踩过,还敢说你做过自动化测试?

在执行冒烟测试、回归测试或多浏览器兼容性测试时&#xff0c;利用web自动化测试可以显著节省人力成本&#xff0c;因此web自动化测试的价值非常大。然而&#xff0c;任何从事过web自动化测试的人都会有这样的体会:写自动化代码相对简单&#xff0c;但维护的成本却非常高。一日…