LeetCode 47. 全排列 II

【全排列 II】 考察:回溯算法,全排列问题,树层去重 阅读详情

一、题目

1、题目描述

  给定一个可包含重复数字的序列 nums,按任意顺序 返回所有不重复的全排列。
  样例输入: nums = [1,1,2]
  样例输出: [[1,1,2], [1,2,1], [2,1,1]]

2、基础框架

  • C++ 版本给出的基础框架代码如下:
class Solution {
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
	}
};

3、原题链接

LeetCode 47. 全排列 II
LeetCode 剑指 Offer II 084. 含有重复元素集合的全排列

二、解题报告

1、思路分析

   ( 1 ) (1) (1) 看到全排列,首先想到深度优先搜索。如下图所示,全排列的每个数字,对应了下面图中的每个结点,全排列就是一个 哈米尔顿路 问题。每个结点只访问一次,且一定要访问一次。我每次可以选择一个未访问的结点进行访问,然后继续下一次递归操作。

   ( 2 ) (2) (2) 用一个hash数组标记这个结点有没有被访问过。
   ( 3 ) (3) (3) 将所有的排列都算出来放到一个数组中,然后对数组进行排序去重。
   ( 4 ) (4) (4) 如果对全排列不是很理解,可以参见:夜深人静写算法(一)- 搜索入门。

2、时间复杂度

   O ( n ! ) O(n!) O(n!)。

3、代码详解

class Solution {
    int hash[10];
    int val[10], valcnt;
    vector<int> stk;
    vector<vector<int>> ret;

    bool same(vector<int>& a, vector<int>&b) {
        for(int i = 0; i < a.size(); ++i) {
            if(a[i] != b[i]) {
                return false;
            }
        }
        return true;
    }

    void dfs(int idx, int depth) {
        int i;
        if(depth == valcnt) {
            if(ret.size() && same(ret[ret.size()-1], stk)) {
                return ;
            }

            ret.push_back(stk);
            return ;
        }

        for(i = 0; i < valcnt; ++i) {
            if(hash[i]) {
                continue;
            }
            stk.push_back(val[i]);
            hash[i] = 1;
            dfs(i, depth + 1);
            hash[i] = 0;
            stk.pop_back();
        }
    }
public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        int i;
        int n = nums.size();
        valcnt = n;
        ret.clear();
        stk.clear();
        memset(hash, 0, sizeof(hash));
        sort(nums.begin(), nums.end());
        for(i = 0; i < n; ++i) {
            val[i] = nums[i];
        }

        for(i = 0; i < n; ++i) {
            stk.push_back(val[i]);
            hash[i] = 1;
            dfs(i, 1);
            hash[i] = 0;
            stk.pop_back();
        }
        int size = 0;
        sort(ret.begin(), ret.end());
        for(i = 0; i < ret.size(); ++i) {
            if(!i || !same(ret[size-1], ret[i])) {
                ret[size++] = ret[i];
            }
        }
        while(ret.size() > size) {
            ret.pop_back();
        }

        return ret;
    }
};



三、本题小知识

  对于一个数据量只有 7 或者 8 的问题,直接穷举所有情况, O ( n ! ) O(n!) O(n!) 也是可以接受的。


四、加群须知

  相信看我文章的大多数都是「 大学生 」,能上大学的都是「 精英 」,那么我们自然要「 精益求精 」,如果你还是「 大一 」,那么太好了,你拥有大把时间,当然你可以选择「 刷剧 」,然而,「 学好算法 」,三年后的你自然「 不能同日而语 」。
  那么这里,我整理了「 几十个基础算法 」 的分类,点击开启:

🌌《算法入门指引》🌌

  如果链接被屏蔽,或者有权限问题,可以私聊作者解决。

  大致题集一览:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述



在这里插入图片描述


  为了让这件事情变得有趣,以及「 照顾初学者 」,目前题目只开放最简单的算法 「 枚举系列 」 (包括:线性枚举、双指针、前缀和、二分枚举、三分枚举),当有 一半成员刷完 「 枚举系列 」 的所有题以后,会开放下个章节,等这套题全部刷完,你还在群里,那么你就会成为「 夜深人静写算法 」专家团 的一员。
  不要小看这个专家团,三年之后,你将会是别人 望尘莫及 的存在。如果要加入,可以联系我,考虑到大家都是学生, 没有「 主要经济来源 」,在你成为神的路上,「 不会索取任何 」。
  🔥联系作者,或者扫作者主页二维码加群,加入刷题行列吧🔥


🔥让天下没有难学的算法🔥

C语言免费动漫教程,和我一起打卡!
🌞《光天化日学C语言》🌞

让你养成九天持续刷题的习惯
🔥《九日集训》🔥

入门级C语言真题汇总
🧡《C语言入门100例》🧡

组团学习,抱团生长
🌌《算法零基础100讲》🌌

几张动图学会一种数据结构
🌳《画解数据结构》🌳

竞赛选手金典图文教程
💜《夜深人静写算法》💜
LeetCode 第47题:全排列 II 通过对LeetCode第47题——全排列 II的详细剖析,我们学习了如何处理包含重复元素的全排列问题。通过回溯法结合排序和剪枝,我们可以高效地生成所有不重复的排列。这种方法不仅在排列问题中非常有效,还可以应用于其他需要处理重复元素的场景。 阅读详情

相关推荐

LeetCode47

我们需要找到数组中所有不重复的全排列。由于数组可能包含重复数字,因此需要避免生成重复的排列。

AI+全栈,AI+应用,实操落地,前沿技术 888

leetcode:47. 全排列 II

题目来源 leetcode 题目描述 题目解析 leetcode:46. 全排列,和之前不同的是,这道题需要去重。 什么是重复呢?存在相同数字,比如 [1,2,2’],那么答案 [1,2,2’] 和 [1,2’,2] 就其实是一样的,在保存结果的时候,我们只选择其一。 我们可以在结果集中去重。但是问题是,结果是一个个列表,怎么知道有木有重复呢? 如果要比较两个列表是否一样: 先看列表长度是不是一样,这道题一定是一样的 既然长度一样,可以先对列表分别进行排序,然后逐个比对。 问题是这样复杂度就太高了

OceanStar的博客 732

C++【力扣LeetCode算法题库】47. 全排列 II

给定一个可包含重复数字的序列 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]] class Solution { public: vector<vector<int>> ans; void trackback

NJU phd 在读。 1349

图解全排列问题_LeetCode 第 47 题:“全排列 II” 图解(简单易懂超详细的解法!!!)...

思路分析:这一题是在 「力扣」第 46 题:“全排列” 的基础上增加了“序列中的元素可重复”这一条件。因此我们还使用“回溯”算法,只不过在构建递归树的过程中需要“剪枝”,以去除重复元素。因为“序列中的元素可重复”,所以得到的“全排列”就会出现重复的结果,因此我们需要想办法把重复的“全排列”去掉。如何去重1、发现困难这道题我们完全可以按照第 46 题,在结果集中去重,不过在实际编码的时候,我们发现并...

weixin_39564386的博客 493

104报文解析工具

可选择包含报文的文本文件或日志文件进行解析,可选择按条数范围或时间范围,输出结果可以在报文解析显示区,也可以输出到文件。可以对文本内容的报文文件进行高级分析,包括遥信遥测等通讯数据的具体信息,通讯帧的统计,通讯次数的统计,各种错误的分析,报文的定位功能,传输的文件具体内容等。输入完成后点击工具栏的解析报文按钮或使用右键菜单的解析就可以对报文进行解析。在报文输入区输入待解析报文并解析后,解析结果就显示在报文解析显示区和报文定位展示区及报文定位条目区。当有多条报文解析后,可以通过报文列表树具体定位某条报文。

XZHOUMIN的博客 5947

Ubuntu22.04安装搜狗输入法踩坑实录:从依赖报错到完美解决的完整指南

本文详细解析了在Ubuntu 22.04系统上安装搜狗拼音输入法的完整流程,从解决依赖报错到配置fcitx框架,再到最终优化使用体验。针对常见的dpkg安装错误和fcitx冲突问题,提供了实用的解决方案和命令,帮助用户顺利完成安装并享受流畅的中文输入体验。

palm99的专栏 971

LeetCode 47.全排列 II

LeetCode 47.全排列 II 是一个经典的回溯算法问题,要求生成一个包含重复数字的数组的所有不重复的全排列。与普通的全排列问题(LeetCode 46.全排列)不同,这个问题需要处理数组中的重复元素,避免生成重复的排列。问题描述给定一个可包含重复数字的序列nums,按任意顺序返回所有不重复的全排列。示例示例 1:示例 2:解题思路• 排序:首先对数组进行排序,这样可以方便地处理重复元素。如果两个相邻的元素相同,那么在生成排列时可以跳过重复的分支。

weixin_45524582的博客 684

JWT实战:5分钟搞定Spring Boot集成JWT认证(含完整代码示例)

本文详细介绍了如何在Spring Boot中快速集成JWT认证,提供完整的代码示例和配置指南。通过JWT实现无状态认证,解决分布式系统中的会话管理问题,提升系统扩展性和安全性。涵盖令牌生成、验证、Spring Security整合及生产级优化方案。

weixin_29327525的博客 456

LeetCode 47 全排列 II

LeetCode 47 全排列 II 题目链接 给定一个可包含重复数字的序列,返回所有不重复的全排列。 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 直接用 next_permutation 函数即可,注意有重复元素所以要判重,AC代码如下: class Solution { public: vector<vector<int>> permuteUnique(vector<int>& n

旺崽的博客 2645

OpenClaw实战五|企业文档AI助理:对接内部知识库+自动答疑+文档生成,员工自助查资料零等待

企业最大的隐性成本,不是设备、不是房租,而是内部知识的混乱与流失。OpenClaw企业文档AI助理,本质是给企业做了一个7×24小时在线、永不疲倦、精准无误、自动更新的内部知识管家。它不替代HR、行政、IT,而是把他们从无穷无尽的重复问答、机械文档编写里解放出来,去做更有价值的管理、服务、优化工作。对中小企业来说,不用买昂贵的知识库系统、不用招开发、不用做复杂集成,一台私有化服务器,两天就能落地,性价比拉满。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 144

【DRAM存储器六十一】LPDDR5介绍--LPDDR5/5X/4/4X IO结构

简述LPDDR5/5X/4/4X IO结构及等效电路下的VREF理论值计算

highman110的博客 480

LeetCode 47全排列II

LeetCode 47全排列II 题目简述:给定一个可包含重复数字的序列,返回所有不重复的全排列。 输入:[1, 1, 2] 输出:[ [1,1,2], [1,2,1], [2,1,1]] 思路:DFS + 回溯 + 剪枝 在一定会产生重复结果集的地方剪枝。产生重复结点的地方,正是图中标注了“剪刀”,且被绿色框框住的地方。 搜索过程只要遇到起点一样,就有可能产生重复。 在图中 ② 处,搜索的数也和上一次一样,但是上一次的 1 还在使用中; 在图中 ① 处,搜索的数也和上一次一样,但是上

XBlog 609

大疆司空 2 私有化部署:FH2、Terra、4G 三大服务区别详解

摘要: 司空2私有版包含三大模块:FH2(核心平台,必选)、Terra(建模算力,需NVIDIA显卡)、4G(内网图传)。FH2是基础,支持设备管理与任务调度;Terra适用于测绘建模场景,依赖GPU算力;4G模块保障复杂环境下的图传稳定性,适合纯内网部署。选择逻辑:先部署FH2,再按需添加Terra(需显卡)或4G(需内网支持),避免资源浪费。

2501_93651177的博客 576

【LeetCode 47】全排列 II

题目描述 给定一个可包含重复数字的序列,返回所有不重复的全排列。 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 解题思路 这个题目和【LeetCode 46】全排列相似,只是这到题目中的元素可能是重复的,下面以题目中给的[1,1,2]为例: 红色部分是需要剪掉的枝。这些路径上包含重复和元素和重复的结果。 首先,我们需要对数组元素进行排序,便于后面前后两个元素进行对比。其他步骤和46题完全一致。只是剪枝的判断条件不一样。 最关键的就是下面这

公众号:前端充电宝 509

第1章:认识OpenClaw

OpenClaw是一个开源的 AI 智能体 Gateway 网关项目名称演变:OpenClaw 原名 Clawdbot,因 Anthropic 商标顾虑在 2026年1月27日更名为 Moltbot(过渡名),最终在1月30日确定为 OpenClaw。三个名字本质是同一个项目,功能完全一致。🏠在你的电脑上运行:完全本地部署,数据隐私有保障📁访问本地文件:可以搜索、读取、编辑你电脑上的文件🔌扩展能力:通过Skills(技能)系统无限扩展功能💬多平台使用。

Maynor的博客 2832

车载以太网网络测试-27【SOME/IP-SD简述】

SOME/IP-SD协议是基于IP的可扩展面向服务中间件中的服务发现协议,是汽车电子和嵌入式系统中实现动态服务发现与通信的核心组件。该协议规范详细说明了协议SOME/IP服务发现(SOME/IP-SD)的格式、消息序列和语义。本文将对SOME/IP-SD协议进行详细介绍。

车载网络测试工程师的博客 1953

LeetCode 47——全排列 II

1. 题目 2. 解答 在 LeetCode 46——全排列 中我们已经知道,全排列其实就是先确定某一个位置的元素,然后余下就是一个子问题。在那个问题中,数据没有重复,所以数据中的任意元素都可以放在最后一个位置。 但是,如果数据有重复的话,重复的数据都放在最后则是一样的结果,我们需要进行一个去重。在这里,我们对数据先进行一个排序,然后依次把每个数据都交换到第一个位置,如果它和第一个数据不相等的话...

seniusen的博客 307

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

全排列II(力扣47)

的不同就在于集合中有相同元素,我们唯一多的操作就是在同一层递归中也要去重,其他的都与上一题相同。大家可以结合我下面的代码及详细注释理解此题。

yaodec的博客 450

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

LeetCode 力扣 47. 全排列 II

题目描述(中等难度) 和上一道题类似,不同之处就是给定的数字中会有重复的,这样的话用之前的算法会产出重复的序列。例如,[ 1 1 ],用之前的算法,产生的结果肯定是 [ [ 1 1 ], [ 1 1 ] ],也就是产生了重复的序列。但我们可以在上一题的解法中进行修改从而解决这道题。 解法一 插入 这个没想到怎么在原基础上改,可以直接了当些,在它产生的结果里,对结果去重再返回。对于去重的话,一...

wind_liang的博客 1063

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

golang力扣leetcode 47.全排列II

47.全排列II47.全排列II题解代码 47.全排列II 47.全排列II 题解 上一个元素和当前相同,并且没有访问过就跳过 代码 package main import "sort" func permuteUnique(nums []int) [][]int { result := make([][]int, 0) list := make([]int, 0) vis := make([]bool, len(nums)) sort.Ints(nums) backtrack(nums, v

清风 609

leetcode(力扣) 46. 全排列 & 47. 全排列 II(回溯 & 去重思路详解)

比如刚才的[1,1,1] 在不用startindex的循环中,每一层的每一次都会考虑所有的nums= [1,2,3]里的数值,第一次取1,下一层依旧从[1,2,3]里选,如果没有去重,则又会取1,加入去重之后选择了2,然后选3,正好可以达到目的。上一道题中所给的数组没有重复的值,所以使用非常简单的方法,直接判断了一下当前遍历的元素在path数组里有没有,没有的话再继续操作,而这道题没法用这个方法了,比如[1,1,2]这里有两个1,但是个合法的答案,因为这两个1是不同的元素,只是值相等。

深度不学习!!的博客 754

leetcode47 全排列 II

leetcode47 全排列 II 本题含有重复元素的全排列问题,还是采用连续的同一个数取最后一个的去重方式,不同的是和前面的组合问题的去重稍有不同: 假如一个序列(已排序)是 1 1 2 2 首先明确一点,无论选1还是选2,交换后剩下的序列中2的连续性都不会受到影响。 但是1的连续性会受到影响,例如第一个数选2,交换后的序列就变成 2 1 2 1 这时第二个数的可选取序列就变成了 1 2 1 可见1不连续了。 那么假如是组合问题,实际上当1不连续的时候,已经不会选1了,所选的数字全部

qq_43513855的博客 290

力扣 47 全排列 II

文章目录1、力扣 47 全排列 II1.1 问题描述1.2 示例2、回溯算法2.1 回溯算法百度定义2.2 算法思路2.3 代码 1、力扣 47 全排列 II 1.1 问题描述 给定一个可包含重复数字的序列 nums ,按任意顺序返回所有不重复的全排列。 1.2 示例 示例 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,.

qq_16539009的博客 241

LeetCode第47题_全排列II

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

qq_40263592的博客 1081

LeetCode算法47:全排列II

题目 给定一个可包含重复数字的序列,返回所有不重复的全排列。 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 说明 求解思路与上一题完全相同,理解上可以参考问题46。这里需要思考的是如何排除重复元素的影响。这就是核心关键,最终通过增加一个判断是否已经处理过相同元素的Set存储器来进行判断。 代码 package leetcode_01_50; ...

xihuanyuye的博客 232

力扣46. 全排列和力扣47. 全排列 II(回溯)

46. 全排列 - 力扣(LeetCode) (leetcode-cn.com) 47. 全排列 II - 力扣(LeetCode) (leetcode-cn.com) 46题为回溯的经典模板,回溯问题可以理解为输出不同的排列方式,需要注意的是不同的回溯问题添加条件与选择条件不同,需要自己根据不同问题进行coding,这也是回溯问题的困难所在。 class Solution { List<List<Integer>> res = new ArrayList...

BJERGSEN的博客 1527
上一篇: 【解题报告】力扣 第 275 场周赛
下一篇: LeetCode 40. 组合总和 II
英雄哪里出来
英雄哪里出来 2021年博客之星Top1 2021年博客之星Top1 领域专家: 系统编程技术领域 领域专家: 系统编程技术领域
博客等级 码龄17年 30万+粉丝 1016原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

英雄哪里出来

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

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

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

打赏作者

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

抵扣说明:

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

余额充值