力扣日记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: [乒乓球, 篮球…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
Linux-07 ubuntu 的 chrome 启动不了
文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了,报错如下四、启动不了,解决如下 总结 问题原因 在应用中可以看到chrome,但是打不开(说明:原来的ubuntu系统出问题了,这个是备用的硬盘&a…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
