力扣日记2.20-【回溯算法篇】491. 非递减子序列
力扣日记:【回溯算法篇】491. 非递减子序列
日期:2023.2.20
参考:代码随想录、力扣
ps:放了个寒假,日记又搁置了三星期……(下跪忏悔)
491. 非递减子序列
题目描述
难度:中等
给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。
数组中可能含有重复元素,如出现两个整数相等,也可以视作递增序列的一种特殊情况。
示例 1:
输入:nums = [4,6,7,7]
输出:[[4,6],[4,6,7],[4,6,7,7],[4,7],[4,7,7],[6,7],[6,7,7],[7,7]]
示例 2:
输入:nums = [4,4,3,2,1]
输出:[[4,4]]
提示:
- 1 <= nums.length <= 15
- -100 <= nums[i] <= 100
题解
cpp ver
class Solution {
public:vector<int> path;vector<vector<int>> result;vector<vector<int>> findSubsequences(vector<int>& nums) {// nums.size >= 2if (nums.size() < 2) return result;backtracking(nums, 0, -200); // -100 <= nums[i] <= 100return result;}void backtracking(vector<int>& nums, int startindex, int lastnum) {// 子序列至少有两个值if (path.size() >= 2) result.push_back(path);int used[201] = {0}; // 这里使用数组来进行去重操作,题目说数值范围[-100, 100],在for循环前重置,每个for循环对应一个// for 循环for (int i = startindex; i < nums.size(); i++) {// // 树层去重(如果本次取出元素与上一个元素一样,则跳过该元素)// if (i > startindex && nums[i] == nums[i - 1]) continue;// 注意,本题由于不能对元素进行排序,所以树层中也可能出现不连续元素重复的可能,所以不能简单的用相邻元素重复来去重// 可以用哈希表来去重(或数组)if (used[nums[i] + 100] != 0) continue; // 如果是已经取过的元素,则跳过该元素used[nums[i] + 100] = 1; // 记录该元素// 如果本次取出元素比上一次取的元素低,则不进入递归,但不结束for循环// (注意取值可不连续!!!如[4,7,6,7]中[4,7,7]也是递增子序列,所以这里不能break)if (nums[i] < lastnum) continue;// 处理节点path.push_back(nums[i]);backtracking(nums, i + 1, nums[i]);path.pop_back();}}
};
复杂度
时间复杂度: O(n * 2^n)
空间复杂度: O(n)
思路总结
- 本题首先要明确“递增子序列”的概念
- 子序列问题本质上是子集问题
- 递增子序列(或者说非递减子序列)是可以从原集合中非连续取值的!!!
- 这点是易错点,且单从题目描述或例子中不能得出此结论(但经过测试用例确实如此)
- 以[4,7,6,7]为例子,[4,7,7]或[7,7]也是其子序列(这是不同于只能连续取值的字符串子串的)
- 所以本题在去重时,不能像 90.子集 II 那样通过相邻元素相同来去重(那种去重思路仅适用于能先对原集合进行排序的情况,但本题提前排序会改变原集合的非递增性质故不能提前排序),因为可能会在不连续的地方出现重复的元素。
- 可以通过哈希表的方法来去重(如用哈希set或效率更高的数组),如代码所示
- 每层for循环都对应一个数组来记录某元素是否已经取过,如果已经取过,则跳过该元素,即:
int used[201] = {0}; // 这里使用数组来进行去重操作,题目说数值范围[-100, 100],在for循环前重置,每个for循环对应一个// for 循环for (int i = startindex; i < nums.size(); i++) {//用哈希表来去重(或数组)if (used[nums[i] + 100] != 0) continue; // 如果是已经取过的元素,则跳过该元素used[nums[i] + 100] = 1; // 记录该元素...
- 每层for循环都对应一个数组来记录某元素是否已经取过,如果已经取过,则跳过该元素,即:
- 可以通过哈希表的方法来去重(如用哈希set或效率更高的数组),如代码所示
- 对于需要为“递增子序列”的判断,实际上也是能否进行取值和递归(即所谓处理节点)的前提条件,即只有当前值不小于上一次取的值,才能进行取值和递归:
- 首先用
last_num
作为参数来记录上一次取的值,即在递归时令last_num = nums[i]
,并且在满足上面的去重条件后,通过if (nums[i] < lastnum) continue;
来过滤不满足递增条件的元素。 - 这里也可以不用
last_num
作为递归参数,而是用if (!path.empty() && nums[i] < path.back()) continue
来表示,因为path.back()
即为上一个取的值(前提是path不为空) - 同时注意不能用
break
而要用contnue
,理由是子序列的取值可以不连续,即使当前值不满足递增,其后面的元素也可能满足,因此不能直接break!!!
- 首先用
- 树形结构示意图
- 可见其中存在两种不符合条件的情况,一是“同一父节点下本层重复使用”,对应去重;二是“所取元素小于子序列最后一个元素”,对应“递增”条件。
- 三部曲:
- 返回值及传递参数:参数为经典的原数组
nums
以及startindex
记录for循环取值的起始位置,除此之外,还用一个last_num
记录递归纵向遍历中的上一个取值 (如果直接用path.back()
表示则不需要此参数) - 终止条件:对于子集问题,由于需要遍历各个节点进行存储,所以不需要专门的终止条件。这里注意子序列至少包含两个值,即path需要满足
size>=2
- 注:在原先的代码实现中,本来是在终止条件处实现递增条件的判断(即当出现小于上一个取值的元素,则终止),但是这样会使得最后一个path的存储非常麻烦,所以作废,还是需要将此递增条件的判断作为for循环中、处理节点(即取值并递归)的前提条件。
- for循环处理:
- 去重(哈希表记录重复元素,重复则跳过)
- 递增条件(小于上一个取值则跳过)
- 处理节点(取值、递归、回溯)
- 返回值及传递参数:参数为经典的原数组
相关文章:

力扣日记2.20-【回溯算法篇】491. 非递减子序列
力扣日记:【回溯算法篇】491. 非递减子序列 日期:2023.2.20 参考:代码随想录、力扣 ps:放了个寒假,日记又搁置了三星期……(下跪忏悔) 491. 非递减子序列 题目描述 难度:中等 给你一…...

Android 13.0 SystemUI下拉状态栏定制二 锁屏页面横竖屏解锁图标置顶显示功能实现
1.前言 在13.0的系统rom定制化开发中,在关于systemui的锁屏页面功能定制中,由于在平板横屏锁屏功能中,时钟显示的很大,并且是在左旁边居中显示的, 由于需要和竖屏显示一样,所以就需要用到小时钟显示,然后同样需要居中,所以就来分析下相关的源码,来实现具体的功能 如图…...

FPGA_简单工程_拨码开关
一 框图 二 波形图 三 代码 3.1 工程代码 module bomakiaguan (input [15:0] switch, // 输入16路拨码开关output reg [15:0] led // 输出16个LED灯 );always (switch) beginled < switch; // 将拨码开关的值直接赋给LED灯 end // 将拨码开关的值直接赋给LED灯 endmodu…...

LaunchPad 市场的复苏,Penpad 成新兴生力军
以 Fair Launch 为主要启动方式的铭文市场的爆发,推动了 LaunchPad 市场的复苏,绝多数所铭文项目都能通过 Fairr Launch 的方式筹集资金实现启动,该赛道的爆发不仅推动了数百亿美元的热钱开始在链上不断涌动,同时也进一步形成了新…...

知识图谱实战应用30-基于py2neo的天文学中的恒星、行星与卫星之间的关系知识图谱研究与应用
大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用30-基于py2neo的天文学中的恒星、行星与卫星之间的关系知识图谱研究与应用。本文将详细介绍如何利用py2neo构建天文学中的恒星、行星与卫星之间的关系知识图谱,并探讨其在天文学研究中的应用。文章将提供多条太阳系中恒…...

笔试题详解(C语言进阶)
前言 欢迎阅读本篇文章!本篇文章通过一个笔试题来加强我们对C语言的理解,希望对你有帮助。后续我会写一个栏目,集合我见到的C语言题目,进行分析讲解。 1、题目一 判断下面程序的输出结果:(下面说的地址4/8字节是因为对…...

ClickHouse快速上手
简介 ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS) 官网(https://clickhouse.com/docs/zh)给出的定义,其实没看懂 特性 ClickHouse支持一种基于SQL的声明式查询语言,它在许多情况下与ANSI SQL标准相同。使用时和MySQL有点相似&#…...

蓝桥杯DP算法——背包问题(C++)
目录 一、01背包问题 二、完全背包问题 三、多重背包问题 四、多重背包问题(优化版) 五、分组背包问题 一、01背包问题 01背包问题就是有N件物品,一个空间大小为V的背包,每个物品只能使用一次,使得背包中所装物品…...
【LeetCode+JavaGuide打卡】Day22|235. 二叉搜索树的最近公共祖先、701.二叉搜索树中的插入操作、450.删除二叉搜索树中的节点
学习目标: 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 学习内容: 235. 二叉搜索树的最近公共祖先 题目链接&&文章讲解 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最…...
Stable Diffusion WebUI 界面介绍
本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 大家好,我是水滴~~ 本文主要对 Stable Diffusion WebUI 的界面进行简单的介绍,让你对该 WebUI 有个大致的了解,为后面的深入学习打下一个基础。主要内容包括:Stable Diffusion 模型(Stable Diffusion checkp…...

Cocos2dx-lua ScrollView[一]基础篇
一.ScrollView概述 cocos游戏中ScrollView控件大量使用,95%以上的项目都会使用ScrollView,个别游戏可能全部使用翻页的滑动效果。如果想要精通Cocos的UI开发,精通ScrollView控件非常关键,因此对ScrollView的使用进行总结很有必要。 下文缩写说明:sv = ScrollView, item代…...

QT应用软件【协议篇】周立功CAN接口卡代码示例
文章目录 USBCAN系列CAN接口卡规格参数资料下载QT引用周立功的库安装sdk代码USBCAN系列CAN接口卡 USBCAN系列CAN接口卡兼容USB2.0全速规范,可支持1/2/4/8路CAN接口。采用该接口卡,PC机可通过USB连入CAN网络,进行CAN总线数据采集和处理,主要具备以下几大优势特点: 支持车载…...

JVM对象的创建流程与内存分配
对象的创建流程与内存分配 创建流程对象内存分配方式内存分配安全问题对象内存分配流程【重要】:对象怎样才会进入老年代?重点 案例演示:对象分配过程大对象直接进入老年代02-对象内存分配的过程: 创建流程 加载 验证 解析 准备 初始化 使用 写在 对象内存分配方式 内存分配…...

docker (六)-进阶篇-数据持久化最佳实践MySQL部署
容器的数据挂载通常指的是将宿主机(虚拟机或物理机)上的目录或文件挂载到容器内部 MySQL单节点安装 详情参考docker官网文档 1 创建对应的数据目录、日志目录、配置文件目录(参考二进制安装,需自己建立数据存储目录) mkdir -p /data/mysq…...

力扣题目训练(17)
2024年2月10日力扣题目训练 2024年2月10日力扣题目训练551. 学生出勤记录 I557. 反转字符串中的单词 III559. N 叉树的最大深度241. 为运算表达式设计优先级260. 只出现一次的数字 III126. 单词接龙 II 2024年2月10日力扣题目训练 2024年2月10日第十七天编程训练,今…...
【react】react中和vue中的provide/inject、context写法示例
react写法 在 React 中,provide和inject的功能类似于 Vue.js 中的 provide和inject。它们都是用于跨组件层次传递数据的。 在 React 中,没有内置的 provide 和 inject 函数。但是,你可以使用 React 的 Context 来实现类似的功能。 Context…...
MySQL 的存储引擎(基本介绍)
文章目录 前言MySQL 的存储引擎介绍存储引擎是什么?存储引擎的特性? Innodb 与 Mylsam 的区别行级锁与表级锁是否支持事务是否支持恢复数据是否支持外键是否支持 MVCC 总结 前言 好文章不要错过,前两天跟大家分享的文章 1.MySQL的基础架构 2.SQL语句的…...
Unity3D 实现基于物理引擎的绳子关节解析详解
前言 在游戏开发中,有时候我们需要实现绳子关节效果,比如在射击游戏中射击绳子,或者在平衡游戏中使用绳子作为支撑。本文将详细介绍如何使用Unity3D的物理引擎实现绳子关节效果。 对惹,这里有一个游戏开发交流小组,希…...

C语言二级易忘易错易混知识点(自用)
1.数组名不能自加。 因为数组名实际上是一个指针,指向数组的第一个元素的地址。数组名在编译器中被视为常量,它的值是固定的,不能改变。 要访问数组的不同元素,应该使用数组名加上偏移量的方式来访问。 2.共用体只有最后一次赋值…...

js_三种方法实现深拷贝
深拷贝( 递归 ) 适用于需要完全独立于原始对象的场景,特别是当对象内部有引用类型时,为了避免修改拷贝后的对象影响到原始对象,就需要使用深拷贝。 // 原始对象 const obj { uname: Lily,age: 19,hobby: [乒乓球, 篮球…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...