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

【算法练习Day24】递增子序列全排列全排列 II

在这里插入图片描述

​📝个人主页:@Sherry的成长之路
🏠学习社区:Sherry的成长之路(个人社区)
📖专栏链接:练题
🎯长路漫漫浩浩,万事皆有期待

文章目录

  • 递增子序列
    • 容易出错的地方
  • 全排列
  • 全排列 II
  • 总结:

递增子序列

491. 递增子序列 - 力扣(LeetCode)
在这里插入图片描述

递增子序列也是一道求子集的问题,但是这道题与子集II的不同之处是,这道题不能够对数组排序,而且要求求出答案序列为2以上的递增子序列。

不能排序求递增子序列是有点难度的,需要一些技巧,首先给定数组nums可能含有重复数据,而做过往期的朋友都知道,去重是一定要排序的,那么不排序我们怎么做呢?

思路是这样的,在函数实现的内部,我们定义一个哈希表,该哈希表存储的是当前数层中我们取过那些数据,取过的我们标记一下,这里用数组还是其他什么做哈希都可以,但是数组更高效。

代码如下:

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>&nums,int startIndex){if(path.size()>1){result.push_back(path);}unordered_set<int> uset;for(int i=startIndex;i<nums.size();i++){if((!path.empty()&&nums[i]<path.back())||uset.find(nums[i])!=uset.end()){continue;}uset.insert(nums[i]);path.push_back(nums[i]);backtracking(nums,i+1);path.pop_back();}}vector<vector<int>> findSubsequences(vector<int>& nums) {result.clear();path.clear();backtracking(nums,0);return result;}
};

没有接触过不能排序而去重的逻辑,有时候还真的想不出来这种解法,因为它是在递归函数内部中间创建的哈希表,我们并不需要对它进行回溯,原因是每进入下一层递归,也就是增加了递归深度它会新建一个哈希,来保存当前树层所插入过的节点,换句话说它保存的是树的横向结构。我们在for循环中,通过判断该层的哈希里要插入的数据有没有插进去过,即可完成数层去重。而控制递增子序列就显得格外简单了,我们仅仅是比较一下当前我们要插入的合法数据和要插入的数组的最后一个数据谁大就可以了,如果要插入的大直接插入,不行的话还是continue,理由还是相同的,continue是为了能让i往后走,找之后的数据看看能不能接着插入进数组。

容易出错的地方

由于我们是根据题目给定数组nums对应的个数据做的哈希,为了判断这个数是否在该树层用过。当我们用数组做哈希结构,要注意测试用例的数据范围,数据包含负数,且是-100-100的数据,所以我们用201个空间并且使数据主动加上100,来避免对负数下标的访问,这是有讲究的定义数组,而非随便取数组大小。当然选用set或者map可以避免这方面的判断,但是当数据范围不大时候,选用数组做哈希可以提高运行效率。

全排列

46. 全排列 - 力扣(LeetCode)
在这里插入图片描述

终于进到了回溯算法的下一个主题,全排列,到了排列部分也就意味着我们的回溯算法例题,快要进入尾声了。排列和组合的模板不同。换句话说,组合问题,子集问题,切割问题三种问题实际上都可以类比为组合问题的大类里面,因为无论是子集问题还是切割问题,都是不能向前去取数

但是排列可以,{1,2}和{2,1}是完全不同的排列,这就意味着我们在写递归时要考虑到这一点,如何即清楚我们下一层从哪里开始,又要可以遍历到这个数之前的数据呢?答案是用到一个数组来保存,这个数组标识着我们哪些数已经取过了,哪些数没有取,也就是说排列问题(往回取数的问题)无论是否涉及到去重都要加入一个标记数组。

先看代码分析

class Solution {
public:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& nums,vector<bool>&used){if(path.size()==nums.size()){result.push_back(path);return;}for(int i=0;i<nums.size();i++){if(used[i]==true){continue;}used[i]=true;path.push_back(nums[i]);backtracking(nums,used);path.pop_back();used[i]=false;}}vector<vector<int>> permute(vector<int>& nums) {result.clear();path.clear();vector<bool> used(nums.size(),false);backtracking(nums,used);return result;}
};

用标记数组是如何实现的呢?在取数之后做标记,往深层递归时,由于被取过的数仍然被标记着,我们可以让i=0每次让它从第一个数开始找,碰到没有被标记的我们直接加入path中,那么是如何像示例中一样,由{1,2,3}逐渐转变为{2,1,3}的呢?实际上也是由于回溯,回溯删除1之后,此时i=0上去i++变为1,这个时候取到的是nums[1]也就是2了,递归问题的取数有时候会突然想不明白,可以自己用编译器调试一下看看,递归是如何进行的,回溯又是如何回溯的,多调试才有利于对递归更深的了解。

全排列 II

47. 全排列 II - 力扣(LeetCode)
在这里插入图片描述

知道了全排列的做法,那么全排列II也就变得简单一些了,一样的套路加上对数据的树层(横向上)去重就可以达到题目要求的效果了。这里可能会想,我们这道题的去重也要重新定义一个新的数组来保存吗?

肯定是不需要的,我们的标记数组也就是去重数组,因为它们都是起到标记一个数是否被取到,所以两个思路用一个数组是完全可以的。依旧是将给定数组先进行排序,使相同的数据挨在一起,这样才有利于排序,去重时完全按照以往去重的规则。

class Solution {
private:vector<vector<int>> result;vector<int> path;void backtracking (vector<int>& nums, vector<bool>& used){// 此时说明找到了一组if (path.size() == nums.size()) {result.push_back(path);return;}for (int i = 0; i < nums.size(); i++) {// used[i - 1] == true,说明同一树枝nums[i - 1]使用过// used[i - 1] == false,说明同一树层nums[i - 1]使用过// 如果同一树层nums[i - 1]使用过则直接跳过if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {continue;}if (used[i] == false) {used[i] = true;path.push_back(nums[i]);backtracking(nums, used);path.pop_back();used[i] = false;}}}
public:vector<vector<int>> permuteUnique(vector<int>& nums) {result.clear();path.clear();sort(nums.begin(), nums.end()); // 排序vector<bool> used(nums.size(), false);backtracking(nums, used);return result;}
};

看到这个代码可能有同学会产生疑惑,我们这里还用used[i]来判断,那出现数组相同数据时候例如{1,1,2}会不会第二个1进不去啊,这里大可不必担心,因为我们判断的是used[i]也就是标记数组的位置,是第一个位置还是第二个位置是否为1的判断,与你本身数值是什么没有任何关系,这一点一定要注意。

总结:

今天我们完成了递增子序列、全排列、全排列 II三道题,相关的思想需要多复习回顾。接下来,我们继续进行算法练习。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

在这里插入图片描述

相关文章:

【算法练习Day24】递增子序列全排列全排列 II

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 递增子序列容易出错的地方 …...

web3之链上情报平台Arkham

文章目录 web3之链上情报平台Arkham什么是Arkham链上情报交易所 Arkham Intel Exchange相较于传统情报交易方式,Arkham Intel Exchange下优势 web3之链上情报平台Arkham 什么是Arkham 官网&#xff1a;https://zh.arkhamintelligence.com/ 官方&#xff1a;https://platform.…...

浅谈uniapp中开发安卓原生插件

其实官方文档介绍的比较清楚而且详细,但是有时候他太墨迹,你一下子找不到自己想要的,所以我总结了一下开发的提纲,也是为了自己方便下次使用。 1.第一步,下载官方提供的Android的示例工程,然后倒入UniPlugin-Hello-AS工程请在App离线SDK中查找,之后Android studio,编译运行项目…...

音频格式WAV

查找wav文件头关键struct 位置&#xff0c;当然也可查找avi文件头。用这个方法找到avi文件data位置后&#xff0c;可直接读出文件的每一帧图片。当然avi数据的标志位不是data,可以是00dc等。 WAV音频头文件有三个关键struct&#xff1a;RIFF, fmt,data。 AVI 视频文件头的关键…...

《语音优先》智能语音技术驱动的交互界面设计与语音机器人设计(译者序)...

“言为心声,语为心境”&#xff0c;语言与对话是我们沟通与协作的重要方式。而智能语音技术是一种基于人工智能和自然语言处理技术的语音交互技术。它可以通过语音识别技术将用户的语音指令转换为文本&#xff0c;然后通过自然语言处理技术对文本进行分析和理解&#xff0c;最终…...

[SQL开发笔记]WHERE子句 : 用于提取满足指定条件的记录

SELECT DISTINCT语句用户返回列表的唯一值&#xff1a;这是一个很特定的条件&#xff0c;假设我需要考虑很多中限制条件进行查询呢&#xff1f;这时我们就可以使用WHERE子句进行条件的限定 一、功能描述&#xff1a; WHERE子句用于提取满足指定条件的记录&#xff1b; 二、WH…...

【微信小程序】6天精准入门(第5天:利用案例与后台的数据交互)附源码

一、什么是后台交互&#xff1f; 在小程序中&#xff0c;与后台交互指的是小程序前端与后台服务器之间的数据通信和请求处理过程。通过与后台交互&#xff0c;小程序能够获取服务器端的数据、上传用户数据、发送请求等。 小程序与后台交互可以实现数据的传输、用户认证、实时消…...

【Hydro】水文模型比较框架MARRMoT - 包含47个概念水文模型的Matlab代码

目录 说明源代码运行实例workflow_example_1.mworkflow_example_2.mworkflow_example_3.mworkflow_example_4.m 测试1、 结构体兼容性问题2、append的兼容性问题3、修改后的MARRMoT_model.m 说明 MARRMoT是一个新的水文模型比较框架&#xff0c;允许不同概念水文模型结构之间的…...

Android Studio(2022.3.1)设置阿里云源-新旧版本

新版本 #settings.gradle.ktsmaven { url uri("https://maven.aliyun.com/repository/public/") }maven { url uri("https://maven.aliyun.com/repository/google/") }maven { url uri("https://maven.aliyun.com/repository/jcenter/") }ma…...

SOLIDWORKS 2024新功能 3D CAD三维机械设计10大新功能

SOLIDWORKS 2024新增功能 - 3D CAD三维机械设计 10大新增功能 1. 先前版本的兼容性 •利用您订阅的 SOLIDWORKS&#xff0c;可将您的 SOLIDWORKS 设计作品保存为旧版本&#xff0c;与使用旧版本 SOLIDWORKS 的供应商无缝协作。 •可将零件、装配体和工程图保存为最新版本…...

第十三章:L2JMobius学习 – 玩家攻击怪物

本章节&#xff0c;我们学习一下玩家周边怪物的刷新。在上一章节中&#xff0c;我们提过这个事情。当玩家移动完毕之后&#xff0c;会显示周围的游戏对象&#xff0c;其中就包括NPC怪物。当然&#xff0c;玩家“孵化”自己&#xff08;调用spawnMe方法&#xff09;的时候&#…...

Module not found: Error: Can‘t resolve ‘core-js/modules/es.promise.js‘

1.遇到的问题 具体错误&#xff1a; ERROR in ./src/js/index.js 1:0-48 产环境配置15js兼容性处理srcjsERROR in ./src/js/index.js 2:0-39 Module not found: Error: Cant resolve core-js/modules/es.promise.js in D:DesktopMy FilesRecentlyStudyWebPackdemo3.webpack生…...

09-React路由使用(React Router 6)

9-React Router 6的使用 1.概述 React Router 以三个不同的包发布到 npm 上&#xff0c;它们分别为&#xff1a; react-router: 路由的核心库&#xff0c;提供了很多的&#xff1a;组件、钩子。react-router-dom: 包含react-router所有内容&#xff0c;并添加一些专门用于 DOM …...

Linux上常用网络相关命令

1. ifconfig&#xff1a; - 显示所有网络接口的配置信息&#xff1a;ifconfig - 显示特定网络接口&#xff08;例如eth0&#xff09;的配置信息&#xff1a;ifconfig eth0 2. ip&#xff1a; - 显示网络接口的配置信息&#xff1a;ip addr show - 显示路由表&…...

contenteditable实现文本内容确认提示

功能需求&#xff1a; 列表进行批量查询&#xff0c;需要对输入的值做提交校验&#xff0c;分三种情况&#xff1a; 若部分字符串有误&#xff0c;部分字符串需要变更字体颜色做提示&#xff0c;再次点击确认则对部分正确数据执行批量查询 若全部数据有误则变更字体颜色做提示&…...

vue2vue3--render函数(h)

目录 h函数 方法1. 在Options API中的使用 方法2. 在Composition API中的使用 Vue 2中的渲染函数 ​基础​ vue2 vue3 vue3--声明渲染函数 节点、树以及虚拟 DOM ​虚拟 DOM​ createElement 参数 深入数据对象 约束 vue2 vue3 使用 JavaScript 代替模板功能…...

网络协议--动态选路协议

10.1 引言 在前面各章中&#xff0c;我们讨论了静态选路。在配置接口时&#xff0c;以默认方式生成路由表项&#xff08;对于直接连接的接口&#xff09;&#xff0c;并通过route命令增加表项&#xff08;通常从系统自引导程序文件&#xff09;&#xff0c;或是通过ICMP重定向…...

30天精通Nodejs--第一天:入门指南

介绍 看一下下面这段比较官方的介绍: Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,可以用于构建可扩展的网络应用程序。它的特点在于能够使JavaScript在服务器端运行,能够利用JavaScript的强大功能来处理服务器端的事务。 Nodejs的特点 高效的异步编程:Node.…...

C# ref用法,实现引用传递(地址传递)

前言&#xff1a; 今天这篇文章我们简单学习一下C# ref的用法&#xff0c;在看别人的代码不至于看不懂逻辑&#xff0c;虽然这是一个比较简单的知识点&#xff0c;但是还是值得我们去学习一下关于这个知识点一些概念&#xff0c;我们知道在C# 中我们的函数参数&#xff0c;一般…...

微信小程序数据交互------WXS的使用

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》《Vue.js使用》 ⛺️ 越努力 &#xff0c;越幸运。 1.数据库连接 数据表结构&#xff1a; 数据测式&#xff1a; 2.后台配置 pom.xml <?xml version&quo…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...