当前位置: 首页 > news >正文

力扣日记2.22-【回溯算法篇】47. 全排列 II

力扣日记:【回溯算法篇】47. 全排列 II

日期:2023.2.22
参考:代码随想录、力扣

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]]

提示:

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

题解

cppver
class Solution {
public:
#define SOLUTION 2vector<int> path;vector<vector<int>> result;vector<vector<int>> permuteUnique(vector<int>& nums) {// 排序sort(nums.begin(), nums.end());vector<bool> used(nums.size(), false);backtracking(nums, used);return result;}
#if SOLUTION == 1void backtracking(vector<int>& nums, vector<bool>& used) {  // 因为存在重复值,所以不宜用哈希表记录是否使用过// 终止条件if (path.size() == nums.size()) {result.push_back(path);return;}int lastNum = -11;// for 横向遍历for (int i = 0; i < nums.size(); i++) {// 需要标记哪些值已经取过了 used[i] if (used[i] == true) continue;  // 取过了,则跳过该值// 去重if (nums[i] == lastNum) continue; // 与for循环的上一次取值重复// 否则,标记取过,并进行取值与递归lastNum = nums[i]; // 更新 lastNumused[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}
#elif SOLUTION == 2void backtracking(vector<int>& nums, vector<bool>& used) {  // 因为存在重复值,所以不宜用哈希表记录是否使用过// 终止条件if (path.size() == nums.size()) {result.push_back(path);return;}// 使用 nums[i] == nums[i-1] 结合 used[i-1] 来判断是树枝重复还是树层重复// 树层重复的条件为:i > 0 && nums[i] == nums[i-1] && used[i-1] == false (上一个位置的元素未使用,说明是树层)// 树枝重复的条件为:i > 0 && nums[i] == nums[i-1] && used[i-1] == true// for 横向遍历for (int i = 0; i < nums.size(); i++) {// 树枝(纵向递归):标记哪些值已经取过了 used[i] if (used[i] == true) continue;  // 取过了,则跳过该值// 树层(用于去重)if (i > 0 && nums[i] == nums[i-1] && used[i-1] == false) continue; // 与for循环的上一次取值重复// 否则,标记取过,并进行取值与递归used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}
#endif
};

复杂度

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

思路总结

  • 本题与 46. 全排列 的区别在于,集合中可能存在重复元素。因此,需要考虑去重,即在46题的基础上,需要在for循环遍历(横向遍历)中,过滤掉相同的元素(但又不能影响到纵向递归时元素的可重复选取)。
  • 不同于 40.组合总和 II 和 90.子集 II,全排列在for循环遍历时不能使用startindex,即每次for循环遍历都会从头开始遍历,不能直接在for循环中,用 if (i > 0 && nums[i] == nums[i-1]) continue; 来跳过重复元素,因为这样会使得在纵向递归时也无法选取到重复元素。
  • 因此,需要一个只会影响到横向遍历的变量,即代码中在for循环前定义的lastNum(这样每次for循环前会重置lastNum),用来记录相同层中for循环上次取到的元素——如果当前值与for循环上次取到的值相同,则跳过当前元素。且只有在该值也满足“纵向递归中当前位置未取过”的条件(used[i] == false)才会更新该lastNum(即当前值能进行取值、递归才会更新)。
  • 注意:
    • 去重 要提前做好排序
    • 由于本题存在重复元素,所以不能使用按值大小记录是否取过的哈希表作为used,而要使用按位置记录的usedvector<bool> used(nums.size(), false))。
    • 去重与是否使用过的if-continue判断条件的前后位置不影响(也可以写在一起),但取值、更新、递归、回溯等(所谓处理节点)一定要放在两者后面。
  • 树形结构示意图:
    • 在这里插入图片描述
  • 代码随想录版本:
    • 使用 nums[i] == nums[i-1] 结合 used[i-1] 来判断是树枝重复还是树层重复
      • 树层重复的条件为:i > 0 && nums[i] == nums[i-1] && used[i-1] == false (上一个位置的元素未使用,说明是树层)
      • 树枝重复的条件为:i > 0 && nums[i] == nums[i-1] && used[i-1] == true
      • 如图
      • 在这里插入图片描述
    • 所以在for循环中
      • 第一个条件用于排列取值
        // 树枝(纵向递归):标记哪些值已经取过了 used[i] 
        if (used[i] == true) continue;  // 取过了,则跳过该值
        
      • 第二个条件用于树枝去重
        if (i > 0 && nums[i] == nums[i-1] && used[i-1] == false) continue;
        

相关文章:

力扣日记2.22-【回溯算法篇】47. 全排列 II

力扣日记&#xff1a;【回溯算法篇】47. 全排列 II 日期&#xff1a;2023.2.22 参考&#xff1a;代码随想录、力扣 47. 全排列 II 题目描述 难度&#xff1a;中等 给定一个可包含重复数字的序列 nums &#xff0c;按任意顺序 返回所有不重复的全排列。 示例 1&#xff1a; 输…...

如何理解三大微分中值定理

文章看原文,自己写的只是备份 高等数学强化2:一元函数微分学 中值定理 极值点 拐点_一元函数中值定理-CSDN博客 高等数学强化3:一元函数积分学 P积分-CSDN博客 高等数学强化3:定积分几何应用-CSDN博客...

Linux--自定义shell

shell shell就是操作系统提供给用户与操作系统进行交互的命令行界面。它可以理解为一个用户与操作系统之间的接口&#xff0c;用户可以通过输入命令来执行各种操作&#xff0c;如文件管理、进程控制、软件安装等。Shell还可以通过脚本编程实现自动化任务。 常见的Unix系统中使…...

AIGC 实战:Ollama 和 Hugging Face 是什么关系?

Ollama和 Hugging Face 之间存在着双重关系&#xff1a; 1. Ollama是 Hugging Face 开发并托管的工具&#xff1a; Ollama是一个由 Hugging Face 自行开发的开源项目。它主要用于在本地运行大型语言模型 (LLM)&#xff0c;特别是存储在 GPT 生成的统一格式 (GPT-Generated Un…...

Gitee教程2(完整流程)

1.配置git git config --global user.name "用户名" git config --global user.email "密码" 如何获取&#xff1f; gitee右上角加号点击新建仓库&#xff0c;仓库名随便起一个就行 找到这条命令&#xff0c;把这两句一个一个复制到vscode终端就行 2.创建g…...

Go 1.22 中的 for 循环新特性详解

目录 每次迭代都创建新变量 支持整数类型循环 小结 在 Go 语言中&#xff0c;for 循环是实现迭代的主要方式。Go 中的 for 循环非常灵活&#xff0c;有多种使用方式&#xff0c;包括传统的三部分 for 循环、类似于其他语言中的 while 循环以及迭代集合的 range 循环。 在 1…...

igolang学习2,golang开发配置国内镜像

go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,direct...

R语言空间分析、模拟预测与可视化

随着地理信息系统&#xff08;GIS&#xff09;和大尺度研究的发展&#xff0c;空间数据的管理、统计与制图变得越来越重要。R语言在数据分析、挖掘和可视化中发挥着重要的作用&#xff0c;其中在空间分析方面扮演着重要角色&#xff0c;与空间相关的包的数量也达到130多个。在本…...

体育赛事直播系统软件开发

体育赛事直播系统的软件开发是一个复杂的项目&#xff0c;需要多个方面的准备和工作。以下是开发这样一个系统可能涉及的主要步骤和考虑因素&#xff1a; 需求分析和规划&#xff1a;首先需要明确系统的功能需求&#xff0c;包括直播视频的流媒体处理、用户管理、直播赛事安排…...

使用 kind 集群安装运行极狐GitLab Runner【上】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 关于 kind kind 是一个用来运行本地 Kubernetes 机群的工具&a…...

wine 源码 vk3d wine-gecko wine-mono 各版本 国内下载地址 中国科技技术大学源

下载地址 Index of /wine/...

【ArcGIS微课1000例】0104:二位面状数据转三维多面体(建筑物按高度拉伸)

文章目录 一、加载数据二、添加高度字段三、三维拉伸显示四、生成三维体数据五、注意事项一、加载数据 打开ArcScene,加载配套实验数据(0104.rar中的二维建筑物矢量数据,订阅专栏,获取专栏所有文章阅读权限及配套数据),如下图所示: 二、添加高度字段 本实验将二维数据…...

jquery简介与解析

jQuery是一款流行的JavaScript库&#xff0c;旨在简化客户端脚本编写。它针对DOM操作、事件处理、动画效果和AJAX交互提供了简洁高效的解决方案&#xff0c;使得开发者能够更加便捷地创建交互式网页。 // jQuery小插件&#xff1a;给带有highlight类的元素添加鼠标悬停效果 (fu…...

Apache Commons开源的工具库介绍

Apache Commons 是 Apache 软件基金会主持的一个项目&#xff0c;旨在提供一系列可重用的 Java 组件。这些组件覆盖了从数据封装、文本处理到网络通信等各个方面&#xff0c;是 Java 开发中常用的一系列工具库。Apache Commons 项目下的各个库通常以 "commons-" 开头…...

SQL语法法则

概念 SQL语法规则&#xff1a;SQL是一种结构化编程语言 基础SQL指令通常是以行为单位 SQL指令需要语句结束待&#xff0c;默认是英文分号:;、\g、\G SQL指令类似自然语言 编写的SQL中如果用到了关键字或者保留字&#xff0c;需要使用反引号、来包裹&#xff0c;让系统忽略 …...

Java命令模式:让请求成为对象

Java命令模式&#xff1a;让请求成为对象 在软件设计中&#xff0c;我们经常遇到需要将操作或请求封装成对象的情况。这样&#xff0c;我们可以将它们作为参数传递、排队、记录或撤销。命令模式正是为了满足这种需求而诞生的。在命令模式中&#xff0c;一个请求或操作被封装成…...

研究生摆烂摆烂的一个寒假

寒假&#xff1a;27-24&#xff0c;不到一个月 刚回家&#xff0c;不想学习&#xff0c;摆烂 想学了&#xff0c;又过年了&#xff0c;于是又开摆 又想学了&#xff0c;家里面有有点小事&#xff0c;于是又开摆 摆完&#xff0c;没想到就返校啦 期末作业没完成&#xff08…...

singularity-ce-4.1.0 + go 完整安装步骤,及报错解决

singularity-ce-4.1.0 + go 1.20 完整安装步骤. 解决bug: checking: host Go compiler (at least version 1.13)... not found! mconfig: could not complete configuration服务器基础环境: 阿里云服务器: => lsb_release -a LSB Version: :core-4.1-amd64:core-4.1-n…...

笔记-电感充放电过程状态记录

描述&#xff1a;电感充放电过程状态记录 为加深对电感充放电的理解&#xff0c;特做一次记录。 目录 一、准备工作二、电感状态记录1、电感刚开始充电瞬间2、电感充电期间3、电感充电完毕4、电感开始放电瞬间5、电感放电完毕6、电感充放电完整记录 一、准备工作 1、在线平台…...

石头剪刀布游戏(C语言)

题目描述 石头剪刀布游戏有 3 种出拳形状&#xff1a;石头、剪刀、布。分别用字母 A , B , C 表示。 游戏规则: 出拳形状之间的胜负规则如下&#xff1a; A > B&#xff1b;B > C&#xff1b;C > A&#xff1b;">"左边一个字母&#xff0c;表示相对优…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...