【Leetcode每日一题】 综合练习 - 全排列 II(难度⭐⭐)(71)

news/2024/9/25 8:25:21/

1. 题目解析

题目链接:47. 全排列 II

这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。

2.算法原理

算法思路梳理

为了生成给定数组nums的全排列,同时避免由于重复元素导致的重复排列,我们可以遵循以下步骤和策略:

  1. 预处理与排序
    • 由于题目不要求返回排列的顺序,我们可以首先对nums进行排序,使得所有相同的元素相邻。这样方便后续操作,因为我们可以根据元素的顺序来避免产生重复的全排列。
  2. 定义递归函数
    • 设计一个递归函数backtrack(vector<int>& nums, int idx),其中idx表示当前需要填充的位置。该函数用于搜索并存储所有合理的排列。
  3. 初始化数据结构
    • 使用一个二维数组ans来存储所有可能的排列。
    • 使用一个一维数组perm来保存当前状态下的排列。
    • 使用一个一维数组visited来标记元素是否已经被选择用于当前排列。
  4. 递归过程
    • 递归终止条件:当idx等于nums的长度时,说明已经处理完所有数字,此时将perm数组加入ans
    • 递归状态转移:对于每个下标i,如果nums[i]未被标记(即visited[i]为0),并且如果它之前的相同元素(如果存在)已被标记,则执行以下步骤:
      • 标记visited[i]为1,表示nums[i]已被选择用于当前排列。
      • nums[i]添加到perm数组的末尾。
      • 递归调用backtrack函数,处理下一个位置(即idx+1)。
      • 递归返回后,进行回溯操作:将visited[i]重新设为0,并从perm数组中移除nums[i]
  5. 注意事项
    • 在选择元素时,必须确保相同元素按照它们在排序后数组中的顺序出现在排列中。这样可以确保不会产生重复的全排列。
    • 如果当前元素之前的相同元素未被选择(即未被标记),则当前元素也不能被选择,这同样是为了避免重复排列。
  6. 返回结果
    • 递归完成后,ans数组将包含所有不重复的全排列。

算法实现细节

  • 在递归函数中,需要仔细处理边界条件和状态转移的逻辑,确保每次递归调用都符合题目要求。
  • 使用visited数组可以有效地避免重复选择相同的元素,尤其是在处理含有重复元素的数组时。
  • 回溯操作是深度优先搜索中的重要步骤,它允许我们撤销之前的选择,并尝试其他可能性。

3.代码编写

class Solution {vector<int> path;vector<vector<int>> ret;bool cheak[9];
public:vector<vector<int>> permuteUnique(vector<int>& nums) {sort(nums.begin(), nums.end());dfs(nums, 0);return ret;}void dfs(vector<int>& nums, int pos){if(pos == nums.size()){ret.push_back(path);return;}for(int i = 0; i < nums.size(); i++){//剪枝是重点,if判断!!!if(cheak[i] == true || (i != 0 && nums[i] == nums[i - 1]) && cheak[i - 1] == false){continue;}path.push_back(nums[i]);cheak[i] = true;dfs(nums, pos + 1);path.pop_back();cheak[i] = false;}}
};

The Last

嗯,就是这样啦,文章到这里就结束啦,真心感谢你花时间来读。

觉得有点收获的话,不妨给我点个吧!

如果发现文章有啥漏洞或错误的地方,欢迎私信我或者在评论里提醒一声~


http://www.ppmy.cn/news/1452854.html

相关文章

用vsCode开发uni-app(vue + ts)项目流程

提示:记录项目创建流程 文章目录 前言一、安装 uni-app 插件二、ts 类型校验1.安装类型声明文件2.配置 tsconfig,json三、json 注释问题四、组件引入1. 安装 uni-app2. 组件自动引入3. 配置 ts 类型五、小程序端 Pinia 持久化六、uni.request 请求封装七、请求成功提取数据和设…

自然科学领域基于ChatGPT大模型的科研绘图

以ChatGPT、LLaMA、Gemini、DALLE、Midjourney、Stable Diffusion、星火大模型、文心一言、千问为代表AI大语言模型带来了新一波人工智能浪潮&#xff0c;可以面向科研选题、思维导图、数据清洗、统计分析、高级编程、代码调试、算法学习、论文检索、写作、翻译、润色、文献辅助…

RabbitMQ之消费者ACK 功能

什么是消费者ACK&#xff1f; 简单说就是 消息确认机制 mq要保证消息能可靠的达到消费者。消费者在消费是是可以指定autoAck参数&#xff08;自动/手动&#xff09;的方式告诉mq自己是否确认收到消息。 当 autoAck 参数为 false 时&#xff0c; 队列中的消息分成了两部分&#…

Arxml文件解析02- 自动驾驶Radar服务radar_svc.arxml

<AUTOSAR xmlns="http://autosar.org/schema/r4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://autosar.org/schema/r4.0 AUTOSAR_00045.xsd

基于Springboot的校园食堂订餐系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园食堂订餐系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【02358单片机原理及应用】第三、四、五章考试复习自考复习

第3章 80C51单片机指令系统 考试知识点&#xff1a; 1、寻址方式 &#xff08;1&#xff09;立即寻址&#xff08;#data&#xff0c;#data16&#xff09;例&#xff1a;MOV A&#xff0c;#00H &#xff08;2&#xff09;直接寻址&#xff08;direct&#xff09;内部RAM…

[数据结构]————排序总结——插入排序(直接排序和希尔排序)—选择排序(选择排序和堆排序)-交换排序(冒泡排序和快速排序)—归并排序(归并排序)

文章涉及具体代码gitee&#xff1a; 登录 - Gitee.com 目录 1.插入排序 1.直接插入排序 总结 2.希尔排序 总结 2.选择排序 1.选择排序 ​编辑 总结 2.堆排序 总结 3.交换排序 1.冒泡排序 总结 2.快速排序 总结 4.归并排序 总结 5.总的分析总结 1.插入排…

使用 Docker-Compose 部署 ZooKeeper + Kafka + Kafka-UI

使用 Docker-Compose 部署 Kafka + ZooKeeper 1. 无密码验证部署1.1 启动 ZooKeeper1.2 查看 zookeeper 状态1.3 启动 Kafka1.4 Kafka 配置文件1.4 使用命令操作 Kafak 生产、消费1.4.1 创建topic1.4.2 查看某个 topic1.4.3 获取所有 topic1.4.4 删除 topic1.4.4 发送消息1.4.5…