【综合算法练习】(第八篇)

目录

全排列Ⅱ(medium)

题目解析

讲解算法原理

编写代码

电话号码的字⺟组合(medium)

题目解析

讲解算法原理

编写代码


全排列Ⅱ(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定⼀个可包含重复数字的序列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

讲解算法原理

解法:算法思路:

因为题⽬不要求返回的排列顺序,因此我们可以对初始状态排序,将所有相同的元素放在各⾃相邻的
位置,⽅便之后操作。因为重复元素的存在,我们在选择元素进⾏全排列时,可能会存在重复排列,例如:[1,2,1],所有的下标排列为:

123
132
213
231
312
321

按照以上下标进⾏排列的结果为:

121
112
211
211
112
121 

可以看到,有效排列只有三种[1,1,2],[1,2,1],[2,1,1],其中每个排列都出现两次。因此,我们需要对相同元素定义⼀种规则,使得其组成的排列不会形成重复的情况:
1. 我们可以将相同的元素按照排序后的下标顺序出现在排列中,通俗来讲,若元素s出现x次,则排序后的第2个元素s⼀定出现在第1个元素s后⾯,排序后的第3个元素s⼀定出现在第2个元素s后⾯,以此类推,此时的全排列⼀定不会出现重复结果。
2. 例如:a1=1,a2=1,a3=2,排列结果为[1,1,2]的情况只有⼀次,即a1在a2前⾯,因为a2不会出现在a1前⾯从⽽避免了重复排列。

3. 我们在每⼀个位置上考虑所有的可能情况并且不出现重复;

4. *注意*:若当前元素的前⼀个相同元素未出现在当前状态中,则当前元素也不能直接放⼊当前状态的数组,此做法可以保证相同元素的排列顺序与排序后的相同元素的顺序相同,即避免了重复排列出现。
5. 通过深度优先搜索的⽅式,不断地枚举每个数在当前位置的可能性,并在递归结束时回溯到上⼀个状态,直到枚举完所有可能性,得到正确的结果。
递归函数设计:voidbacktrack(vector<int>&nums,intidx)参数:idx(当前需要填⼊的位置);
返回值:⽆;函数作⽤:查找所有合理的排列并存储在答案列表中。
递归流程如下:1. 定义⼀个⼆维数组ans⽤来存放所有可能的排列,⼀个⼀维数组perm⽤来存放每个状态的排列,⼀个⼀维数组visited标记元素,然后从第⼀个位置开始进⾏递归;

2. 在每个递归的状态中,我们维护⼀个步数idx,表⽰当前已经处理了⼏个数字;

3. 递归结束条件:当idx等于nums数组的⻓度时,说明我们已经处理完了所有数字,将当前数组存⼊结果中;

4. 在每个递归状态中,枚举所有下标i,若这个下标未被标记,并且在它之前的相同元素被标记过,则使⽤nums数组中当前下标的元素:

a. 将visited[i]标记为1;
b. 将nums[i]添加⾄perm数组末尾;

c. 对第step+1个位置进⾏递归;
d. 将visited[i]重新赋值为0,并删除perm末尾元素表⽰回溯;

5. 最后,返回ans。 

编写代码

c++算法代码:
 

class Solution
{
 vector<int> path;
 vector<vector<int>> ret;
 bool check[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(check[i] == false && (i == 0 || nums[i] != nums[i - 1] || 
check[i - 1] != false))
 {
 path.push_back(nums[i]);
 check[i] = true;
 dfs(nums, pos + 1);
 path.pop_back(); // 恢复现场
 check[i] = false;
 }
 
 }
 }
};

java算法代码:

class Solution
{
 List<Integer> path;
 List<List<Integer>> ret;
 boolean[] check;
 public List<List<Integer>> permuteUnique(int[] nums) 
 {
 path = new ArrayList<>();
 ret = new ArrayList<>();
 check = new boolean[nums.length];
 Arrays.sort(nums);
 dfs(nums, 0);
 return ret;
 }
 public void dfs(int[] nums, int pos)
 {
 if(pos == nums.length)
 {
 ret.add(new ArrayList<>(path));
 return;
 }
 for(int i = 0; i < nums.length; i++)
 {
 // 剪枝
 if(check[i] == false && (i == 0 || nums[i] != nums[i - 1] || 
check[i - 1] != false))
 {
 path.add(nums[i]);
 check[i] = true;
 dfs(nums, pos + 1);
 // 回溯 -> 恢复现场
 path.remove(path.size() - 1);
 check[i] = false;
 }
 }
 }
}

电话号码的字⺟组合(medium)

题目解析

1.题目链接:. - 力扣(LeetCode)

2.题目描述

给定⼀个仅包含数字2-9的字符串,返回所有它能表⽰的字⺟组合。答案可以按任意顺序返回。给出数字到字⺟的映射如下(与电话按键相同)。注意1不对应任何字⺟。
• ⽰例1:
输⼊:digits="23"输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
• ⽰例2:
输⼊:digits=""输出:[]
• ⽰例3:
输⼊:digits="2"输出:["a","b","c"]
• 提⽰:
0<=digits.length<=4
digits[i]是范围['2','9']的⼀个数字。

讲解算法原理

解法:
算法思路:

每个位置可选择的字符与其他位置并不冲突,因此不需要标记已经出现的字符,只需要将每个数字对应的字符依次填⼊字符串中进⾏递归,在回溯是撤销填⼊操作即可。
• 在递归之前我们需要定义⼀个字典phoneMap,记录2~9各⾃对应的字符。
递归函数设计:voidbacktrack(unordered_map<char,string>&phoneMap,string&digits,intindex)
参数:index(已经处理的元素个数),ans(字符串当前状态),res(所有成⽴的字符串);返回值:⽆
函数作⽤:查找所有合理的字⺟组合并存储在答案列表中。
递归函数流程如下:
1. 递归结束条件:当index等于digits的⻓度时,将ans加⼊到res中并返回;
2. 取出当前处理的数字digit,根据phoneMap取出对应的字⺟列表letters;
3. 遍历字⺟列表letters,将当前字⺟加⼊到组合字符串ans的末尾,然后递归处理下⼀个数字(传⼊index+1,表⽰处理下⼀个数字);
4. 递归处理结束后,将加⼊的字⺟从ans的末尾删除,表⽰回溯。
5. 最终返回res即可。

编写代码

c++算法代码:

class Solution
{
 string hash[10] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", 
"tuv", "wxyz"};
 string path;
 vector<string> ret;
public:
 vector<string> letterCombinations(string digits) 
 {
 if(digits.size() == 0) return ret;
 dfs(digits, 0);
 return ret;
 }
 void dfs(string& digits, int pos)
 {
 if(pos == digits.size())
 {
 ret.push_back(path);
 return;
 }
 for(auto ch : hash[digits[pos] - '0'])
 {
 path.push_back(ch);
 dfs(digits, pos + 1);
 path.pop_back(); // 恢复现场
 }
 }
};

java算法代码:

class Solution
{
 String[] hash = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", 
"wxyz"};
 List<String> ret;
 StringBuffer path;
 public List<String> letterCombinations(String digits) 
 {
 ret = new ArrayList<>();
 path = new StringBuffer();
 if(digits.length() == 0) return ret;
 dfs(digits, 0);
 return ret;
 }
 public void dfs(String digits, int pos)
 {
 if(pos == digits.length())
 {
 ret.add(path.toString());
 return;
 }
 String cur = hash[digits.charAt(pos) - '0'];
 for(int i = 0; i < cur.length(); i++)
 {
 path.append(cur.charAt(i));
 dfs(digits, pos + 1);
 path.deleteCharAt(path.length() - 1); // 恢复现场 }
 }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

中间件安全(三)

本文仅作为学习参考使用&#xff0c;本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言: 本文主要讲解apache命令执行漏洞&#xff08;cve_2021_41773&#xff09;。 靶场链接&#xff1a;Vulfocus 漏洞威胁分析平台 一&#xff0c;漏洞简介。 cve_2021_41773漏洞…

双十一我都入手了啥大件?这几款超值好物分享给你

​马上就到一年一度的“双11”大促&#xff0c;简单与大家分享&#xff0c;最近自己买过或者是看好的生活好物。以数码为主&#xff0c;平常的一点生活会提及一些。 耳机党必备&#xff0c;听歌不伤耳朵&#xff01;——南卡OE MIX开放式耳机 一句话推荐&#xff1a;百元旗舰…

PHP海外矿物矿机理财投资源码-金融理财投资源码

PHP海外矿物矿机理财投资源码/金融理财投资源码 海外矿物矿机理财投资源码 测试不错,可以做其他产品理财,功能都没啥太大问题

持续更新...记录

一、Random类 1、构造方法&#xff1a; ①有参&#xff1a;通过指定种子数进行创建 &#xff08;使用相同的种子数创建多个Random对象&#xff0c;这些对象生成的随机数序列将完全相同‌&#xff09; &#xff08;适用于需要可重复生成相同随机数序列的场景&#xff0c;如科学…

Redis项目中应用

1. Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网&#xff1a;https://redis.io 中文网&#xff1a;Redis中文网 2. Redis下载与安装 2.1 Redis下载 Redis安装包分为windows版和Linux版&#xff1a; Wind…

cursor连接远程jupyter

cursor的步骤跟vscode应该是基本一样的&#xff0c;主要需要两个插件&#xff0c;一个是remote-ssh&#xff0c;另一个是jupyter 第一步 首先连接远程的ssh&#xff0c;因为我已经新建好了&#xff0c;所以直接选207&#xff0c;没有连接过的就选Add New SSH Host&#xff…

9款热门CRM客户关系管理系统大盘点

在当今竞争激烈的商业环境中&#xff0c;客户关系管理&#xff08;CRM&#xff09;系统已成为企业不可或缺的工具。CRM系统不仅帮助企业管理客户信息&#xff0c;还能提高销售效率、改善客户服务、增强客户满意度。本文将为您盘点9款热门的CRM客户关系管理系统&#xff0c;并重…

IMX6ULL裸机-汇编_反汇编_机器码

程序处理的4个步骤 我们编写的C程序是不能直接在ARM等平台上运行的&#xff0c;必须经过一系列的程序处理才可以&#xff0c;我们的第一个LED程序涉及两个文件&#xff1a;start.S、main.c&#xff0c;它们的处理过程如下&#xff1a; 对于汇编程序&#xff0c;经过汇编之后&a…

【Unity】游戏UI中添加粒子特效导致穿层问题的解决

这里介绍一下简易的ui系统中&#xff0c;添加粒子特效导致的穿层问题 首先是在ui界面中添加粒子特效预制体&#xff0c;这个时候&#xff0c;控制这个粒子显示层级的有两个方面 上图中&#xff0c;如果你的Sorting Layer ID的值&#xff08;Layer排序&#xff09;是大于当前C…

SAP 根据不同生产版本创建销售预测简介

SAP 根据不同生产版本创建销售预测简介 业务场景前台操作1、创建BOM2、创建工艺路线3、创建生产版本4、创建销售预测5、调整销售预测6、查看物料需求业务场景 很多工厂一个物料可能会存在多个BOM,当有多个BOM存在的情况下就会存在多个生产版本,当创建计划独立需求的时候,系…

STM32 RTC 驱动代码(解决了使用HAL库函数导致的复位或者掉电后导致RTC年月日日期清零的问题)

问题背景&#xff1a;在RTC中断里面使用HAL库HAL_RTC_GetDate()和HAL_RTC_GetTime()来获取RTC时间日期。 源码如下图&#xff1a; 问题描述&#xff1a;单片机断电或者复位后的时分秒的时间可以接上&#xff0c;但年月日的日期就会被清零。如图&#xff1a; 导致问题的根本原因…

SpringBoot3+SpringSecurity6基于若依系统整合自定义登录流程

SpringBoot3SpringSecurity6基于若依系统整合自定义登录流程 问题背景 在做项目时遇到了要对接统一认证的需求&#xff0c;但是由于框架的不兼容性&#xff08;我们项目是springboot3&#xff0c;jdk17&#xff0c;springsecurity6.1.5&#xff09;等因素&#xff0c;不得不使…

Mount Image Pro,在取证安全的环境中挂载和访问镜像文件内容

天津鸿萌科贸发展有限公司从事数据安全服务二十余年&#xff0c;致力于为各领域客户提供专业的数据恢复、数据备份解决方案与服务&#xff0c;并针对企业面临的数据安全风险&#xff0c;提供专业的相关数据安全培训。 天津鸿萌科贸发展有限公司是 GetData 公司数据恢复与取证工…

PHP合成图片,生成海报图,poster-editor使用说明

之前写过一篇使用Grafika插件生成海报图的文章&#xff0c;但是当我再次使用时&#xff0c;却发生了错误&#xff0c;回看Grafika文档&#xff0c;发现很久没更新了&#xff0c;不兼容新版的GD&#xff0c;所以改用了intervention/image插件来生成海报图。 但是后来需要对海报…

React 前端框架全面教程:从入门到进阶

React 前端框架全面教程&#xff1a;从入门到进阶 引言 在现代前端开发中&#xff0c;React 作为一款流行的 JavaScript 库&#xff0c;以其组件化、声明式的特性和强大的生态系统&#xff0c;成为了开发者的首选。无论是构建单页应用&#xff08;SPA&#xff09;还是复杂的用…

基于Python的自然语言处理系列(42):Token Classification(标注分类)

在本篇文章中&#xff0c;我们将探讨如何进行 Token Classification&#xff08;标注分类&#xff09;&#xff0c;这是一类为句子中的每个 token&#xff08;词或子词&#xff09;分配标签的任务。该任务可以解决很多问题&#xff0c;例如命名实体识别&#xff08;NER&#xf…

用Pyhon写一款简单的益智类小游戏——2048

文字版——代码及讲解 代码—— import random# 初始化游戏棋盘 def init_board():return [[0] * 4 for _ in range(4)]# 在棋盘上随机生成一个2或4 def add_new_tile(board):empty_cells [(i, j) for i in range(4) for j in range(4) if board[i][j] 0]if empty_cells:i,…

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 文章目录 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC1. 介绍 二. 参考文献 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 如何在 Ubuntu 22.04 上安装和配置 VNC 1. 介绍 虚拟网络计算…

【Java】方法的使用 —— 语法要求、方法的重载和签名、方法递归

目录 1. 方法基础知识 1.1 方法的概念 1.2 语法格式 * 注意事项【与C不同】 1.3 return —— 返回值的严格检查【比C语言严格】 2. 形参与实参的关系 3. 方法重载 3.1 什么是方法重载&#xff1f;为什么要方法重载&#xff1f; 3.2 方法重载的规则 4. 方法签名 5. 递…

HT7178 带输出关断的20V,14A全集成同步升压转换器

1、特点 输入电压范围VpIN:2.7V-20V 输出电压范围VouT:4.5V-20V 可编程峰值电流:14A 高转换效率: 95%(VPIN7.2V, VoUT 16V, IouT3A) 94%(VPIN12V,VoUT18V,IoUT4A) 90%(VPIN3.3, VoUT-9V,IOUT3A) 轻载条件下两种调制方式:脉频调制(PFM)和 强制脉宽调试(PWM) 集成输出关断的栅极…