回溯算法|491.递增子序列

news2024/10/11 6:30:01

力扣题目链接

class Solution {
private:
    vector<vector<int>> result;
    vector<int> path;
    void backtracking(vector<int>& nums, int startIndex) {
        if (path.size() > 1) {
            result.push_back(path);
            // 注意这里不要加return,要取树上的节点
        }
        unordered_set<int> uset; // 使用set对本层元素进行去重
        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();
        }
    }
public:
    vector<vector<int>> findSubsequences(vector<int>& nums) {
        result.clear();
        path.clear();
        backtracking(nums, 0);
        return result;
    }
};

这题要在理解的“子集II”这题的基础上写会好很多~

代码随想录 (programmercarl.com)

思路

这个递增子序列比较像是取有序的子集。而且本题也要求不能有相同的递增子序列。

这又是子集,又是去重,是不是不由自主的想起了刚刚讲过的90.子集II (opens new window)。

就是因为太像了,更要注意差别所在,要不就掉坑里了!

在90.子集II (opens new window)中我们是通过排序,再加一个标记数组来达到去重的目的。

而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。

所以不能使用之前的去重逻辑!

本题给出的示例,还是一个有序数组 [4, 6, 7, 7],这更容易误导大家按照排序的思路去做了。

为了有鲜明的对比,我用[4, 7, 6, 7]这个数组来举例,抽象为树形结构如图:

491. 递增子序列1

#回溯三部曲

  • 递归函数参数

本题求子序列,很明显一个元素不能重复使用,所以需要startIndex,调整下一层递归的起始位置。

代码如下:

vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums, int startIndex)

  • 终止条件

本题其实类似求子集问题,也是要遍历树形结构找每一个节点,所以和回溯算法:求子集问题! (opens new window)一样,可以不加终止条件,startIndex每次都会加1,并不会无限递归。

但本题收集结果有所不同,题目要求递增子序列大小至少为2,所以代码如下:

if (path.size() > 1) {
    result.push_back(path);
    // 注意这里不要加return,因为要取树上的所有节点
}

  • 单层搜索逻辑

491. 递增子序列1

 在图中可以看出,同一父节点下的同层上使用过的元素就不能再使用了

那么单层搜索代码如下:

unordered_set<int> uset; // 使用set来对本层元素进行去重
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();
}

对于已经习惯写回溯的同学,看到递归函数上面的uset.insert(nums[i]);,下面却没有对应的pop之类的操作,应该很不习惯吧

这也是需要注意的点,unordered_set<int> uset; 是记录本层元素是否重复使用,新的一层uset都会重新定义(清空),所以要知道uset只负责本层!

自己理解的思路:

知识点:

unordered_set和unorder_map很类似,内部都是无序的!
unordered_set是一种无序集合,其底层实现基于hashtable,因此具有快速的查找和删除,添加的优点,因此在需要多次查找和删除的场景里可以用unordered_set来存储数据!

那个去重部分的代码还是不好理解,自己还没完全掌握。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vlookup跨表使用

VLOOKUP&#xff08;查找值&#xff0c;数据表&#xff0c;列序数&#xff0c;匹配条件&#xff09;。打开两表格&#xff0c;输入查找值和表格数据格式一致&#xff0c;查找表格或数据范围是连续的。 跨表VLOOKUP使用步骤&#xff1a; 插函数单元格&#xff0c;输“VLOOKUP()…

各类系统业务功能架构图整理

一、前言 很多软件系统一直经久不衰&#xff0c;主要这些系统都是一些生产工作经营不可或缺的系统。比如财务系统&#xff0c;商城系统&#xff0c;支付系统&#xff0c;供应链系统&#xff0c;人力资源管理系统&#xff0c;ERP系统等等。这些系统不管大公司还是小公司往往都需…

Fastjson 1.2.47 远程命令执行漏洞复现分析环境

Fastjson 1.2.47 远程命令执行漏洞 1、靶机环境安装 1.1、虚机机linux环境参数 1、操作系统&#xff1a;CentOS Linux release 7.4.1708 (Core) 2、IP&#xff1a;192.168.127.1321.1、docker与docker compose安装 1.2、下载https://github.com/vulhub/vulhub/tree/master/…

moment.js 产出未知格式的时间,可能的原因

moment.js 产出未知格式的时间&#xff0c;可能的原因 有个问题困扰我好久了&#xff0c;在项目中使用格式化时间的时候会产出一些千奇百怪的格式&#xff0c;产出的文字我都不认识。 百思不得其解&#xff0c;终于今天在看代码的时候发现了这个问题。 它的表现是这样的&…

Redis中的复制功能(四)

复制的实现 步骤2:建立套接字连接 在SLAVEOF命令执行之后&#xff0c;从服务器将根据命令所设置的IP地址和端口&#xff0c;创建连向主服务器的套接字连接&#xff0c;如图所示。如果从服务器创建的套接字能成功连接(connect)到主服务器&#xff0c;那么从服务器将为这个套接…

第二十一章 RabbitMQ

一、RabbitMQ 介绍 在介绍 RabbitMQ 之前&#xff0c;我们先来看下面一个电商项目的场景&#xff1a; - 商品的原始数据保存在数据库中&#xff0c;增删改查都在数据库中完成。 - 搜索服务数据来源是索引库&#xff08;Elasticsearch&#xff09;&#xff0c;如果数据库商品…

【Redis】Redis的使用

登录redis [roottest2 ~]# redis-cli 127.0.0.1:6379> 或[roottest2 ~]# redis-cli -h 192.168.67.12 -p 6379 192.168.67.12:6379> redis-benchmark 测试工具 redis-benchmark 是官方自带的Redis性能测试工具&#xff0c;可以有效的测试Redis服务的性能 基本的测试语…

稀疏矩阵的三元组表表示法及其转置

1. 什么是稀疏矩阵 稀疏矩阵是指矩阵中大多数元素为零的矩阵。 从直观上讲&#xff0c;当元素个数低于总元素的30%时&#xff0c;这样的矩阵被称为稀疏矩阵。 由于该种矩阵的特点&#xff0c;我们在存储这种矩阵时&#xff0c;如果直接采用二维数组&#xff0c;就会十分浪费…

环形链表问题(判环+寻找入环点)

文章目录 题目1.判断链表中是否有环1.1 思路分析&#xff08;快慢指针&#xff09;1.2 思考&#xff1a;为什么快指针每次走两步&#xff0c;慢指针每次走一步两者一定可以相遇&#xff1f;1.3 快指针一次走3步&#xff0c;走4步&#xff0c;...n步行吗&#xff1f; 题目2. 寻找…

一、企业级架构之LNMP

一、LNMP 概述 1、LNMP之间的关系&#xff1a; LNMP Linux Nginx MySQL PHP 2、配置LNMP服务器&#xff1a; (1) 克隆一台centos7虚拟机&#xff0c;修改 IP 地址 和 UUID 编号。 IP 为 10.1.1.10&#xff0c;UUID 修改后三位。 (2) 设置主机名称&#xff0c;绑定IP地…

机器学习周记(第三十二周:文献阅读-时空双通路框架)2024.3.25~2024.3.31

目录 摘要 ABSTRACT 1 论文信息 1.1 论文标题 1.2 论文摘要 1.3 论文模型 1.3.1 Spatial Encoder&#xff08;空间编码器&#xff09; 1.3.2 Temporal Encoder&#xff08;时间编码器&#xff09; 2 相关代码 摘要 本周阅读了一篇运用GNN进行时间序列预测的论文。论文…

挖一挖:PostgreSQL Java里的double类型存储到varchar精度丢失问题

前言 大概故事是这样的&#xff0c;PostgreSQL数据库&#xff0c;表结构&#xff1a; create table t1(a varchar);然后使用标准的Java jdbc去插入数据&#xff0c;其基本代码如下&#xff1a; import java.sql.*; public class PgDoubleTest {public static void main(Stri…

渐进式图片解决前端在页面中使用大图,图片体积过大导致页面出现白屏现象

1、演示 可以看到&#xff0c;图片还在拼命加载的时候&#xff0c; 页面上就已经有内容了 2、什么渐进式图片 图片一开始是模糊的&#xff0c;然后逐渐的开始变的清晰。如果页面上有一些大图&#xff0c;如果直接扔给浏览器的话那么图片的传输时间就会比较长&#xff0c;用户就…

Java对象Object对象头-MarkWord分析-hashCode

代码主要通过打印对象的内存布局来观察对象头在不同状态下的变化&#xff0c;进而分析对象头在不同情况下的内存布局情况。 System.out.println(ClassLayout.parseInstance(o).toPrintable());&#xff1a;这一行代码通过使用开源库 openjdk.jol 的 ClassLayout 类来解析对象 o…

算法思想堪比哲学,你知多少否?

对算法思想 - 分治算法的理解 分治算法是一种将复杂问题划分为规模较小的子问题&#xff0c;并递归地解决这些子问题&#xff0c;最后将它们的解合并为原问题的解的算法思想。 它具有以下几个关键步骤&#xff1a;分解、解决和合并。 通过将大问题分解为小问题&#xff0c;每个…

数据结构—堆

什么是堆 堆是一种特殊的树形结构&#xff0c;其中每个节点都有一个值。堆可以分为两种类型&#xff1a;最大堆和最小堆。在最大堆中&#xff0c;每个节点的值都大于等于其子节点的值&#xff1b;而在最小堆中&#xff0c;每个节点的值都小于等于其子节点的值。这种特性使得堆…

Linux实验过程

答案截图获取&#xff0c;代写&#xff1a; https://laowangall.oss-cn-beijing.aliyuncs.com/studentall.pdf 基本任务&#xff1a; 1.Linux操作系统安装 2.vi文本编辑 3. Linux用户及文件管理命令 4. Linux权限管理命令 5. Linux网络服务 提高任务&#xff1a; 1、Li…

vue3+elementPlus:实现数字滚动效果(用于大屏可视化)

自行封装注册一个公共组件 案例一&#xff1a; //成功案例&#xff1a; //NumberScroll.vue /* 数字滚动特效组件 NumberScroll */<template><span class"number-scroll-grow"><spanref"numberScroll":data-time"time"class&qu…

intellij idea 使用git的 cherry pick 摘取其他分支的comment

cherry pick 摘取其他分支的comment 如果想把 feature_v1.0 分支的comment 摘到 feature_v1.0_new 分支上&#xff0c; 先切换到 feature_v1.0_new分支&#xff0c;这一步不能少了。然后点击 下面菜单栏的 git&#xff0c;点击Local Changes旁边的 Log&#xff0c;这时能看到…

【Java】打包:JAR、EAR、WAR

打包&#xff1a;JAR、EAR、WAR war 是一个 Web 模块&#xff0c;其中需要包括 WEB-INF&#xff0c;是可以直接运行的 WEB 模块。而 jar 一般只是包括一些 class 文件&#xff0c;在声明了 main_class 之后是可以用 java 命令运行的。 它们都是压缩的包&#xff0c;拿 Tomcat …