回溯算法10-非递减子序列(Java/set去重操作)

10.非递减子序列

  • 题目描述

给你一个整数数组 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]]
  • 题目分析
本题由于是要求解递增子序列,由于所求序列有要求,所以在去重的时候我们不可以将nums先进行排序,再进行递归,这样会使得结果错误,此时我们该如何去重呢?

去重操作

image-20240310100833274

通过上面可以看到,如果发生重复元素,那么它发生在同一树层,以4节点为例,当遍历完4是,需要将集合[7,6,7]依次与4组合,不难看出集合中存在两个7,这一定会造成元素重复,如果将集合变成[7,6]就可以避免这一问题,因此这里可以使用set来去重,这样就可以避免这样情况
Set<Integer> set = new HashSet<>(); // 用于记录当前路径中已经选择过的元素

完整思路

1.首先,我们定义了两个变量:path 和 result。path 是一个链表用于存储当前路径的元素,result 是一个列表用于存储最终的结果。

2.然后,我们定义了一个 findSubsequences 方法,该方法接受一个整数数组 nums 作为参数,并返回所有符合条件的递增子序列列表。在该方法内部,我们调用了 backtrack 方法开始搜索。

3.backtrack 方法是实现回溯的核心部分。它接受两个参数:nums 数组和 startIndex 起始位置。在该方法中,我们首先判断当前路径的长度是否大于1,如果是,说明找到了一个符合条件的递增子序列,将其添加到 result 列表中。

4.然后,我们创建一个 Set<Integer> 集合来记录当前路径中已经选择过的元素,以避免重复选择。接着,我们使用一个循环从 startIndex 开始遍历数组 nums,对于每个元素,如果它已经在路径中存在,或者小于路径末尾元素,则跳过,保证递增性。

5.如果当前元素满足条件,我们将其添加到路径中,同时将其添加到已选择元素的集合中。然后,递归调用 backtrack 方法,将起始位置更新为 i+1,继续搜索下一层。

6.当递归结束后,我们需要将当前元素从路径中移除,以尝试其他可能的组合。
  • Java代码实现
LinkedList<Integer> path = new LinkedList<>(); // 用于存储当前路径的集合
List<List<Integer>> result = new ArrayList<>(); // 用于存储最终结果的列表

/**
 * 寻找数组中长度大于等于2的递增子序列
 * @param nums 给定的整数数组
 * @return 所有符合条件的递增子序列列表
 */
public List<List<Integer>> findSubsequences(int[] nums) {
    backtrack(nums, 0); // 调用回溯函数开始搜索
    return result; // 返回最终结果
}

/**
 * 回溯函数,用于搜索所有可能的递增子序列
 * @param nums 给定的整数数组
 * @param startIndex 当前搜索的起始位置
 */
private void backtrack(int[] nums, int startIndex) {
    if (path.size() > 1) {
        result.add(new ArrayList<>(path)); // 如果当前路径长度大于1,则将该路径加入最终结果
    }
    
    Set<Integer> set = new HashSet<>(); // 用于记录当前路径中已经选择过的元素
    for (int i = startIndex; i < nums.length; i++) {
        if (set.contains(nums[i]) || (!path.isEmpty() && nums[i] < path.get(path.size() - 1))) {
            continue; // 如果当前元素已经在路径中或者小于路径末尾元素,则跳过,保证递增性
        }
        
        path.add(nums[i]); // 将当前元素加入路径
        set.add(nums[i]); // 将当前元素添加到已选择元素的集合中
        backtrack(nums, i + 1); // 递归调用下一层搜索,更新起始位置为 i+1
        path.removeLast(); // 移除当前元素,尝试其他可能的组合
    }
}
  • 代码疑点1:像之前回溯算法一样,set在添加完之后是否需要set.remove()回溯操作呢?
这里是不需要的,因为set处理的逻辑是每一个树层,当遍历同一树层时,即for (int i = startIndex; i < nums.length; i++),此时set要记录这一树层所有的点,因此不需要set.remove()回溯操作,又因为set为局部变量,因此也不会影响其他树层的去重操作
  • **代码疑点2:**判断是否递增怎么做?
我们判断递增子序列,只要知道子序列最后一个元素和当前元素的大小关系就可以了
!path.isEmpty() && nums[i] < path.get(path.size() - 1))
nums[i]:当前元素
path.get(path.size() - 1)):子序列最后一个元素

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

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

相关文章

PyQt6实战1

创建一个json处理的小工具 功能&#xff1a; 1.json格式化 2.jsonpath提取数据 3.保存文件 main.py from PyQt6.QtGui import QFocusEvent from PyQt6.QtWidgets import * from PyQt6.QtCore import * from PyQt6.QtGui import * import sys import json import time impo…

【笔记】原油阳谋论

文章目录 石油的属性能源属性各国石油替代 金融属性黄金石油美元 油价历史油价传导路径 石油供需格局与发展供需格局各国状况美国俄罗斯沙特 产油国困境运输 分析格局分析供需平衡分析价差分析价差概念基本面的跨区模型跨区模型下的价差逻辑 长中短三期分析长期视角——供应看投…

2024年腾讯云99元1年服务器_新老同享_续费99元一年

良心腾讯云推出99元一年服务器&#xff0c;新用户和老用户均可以购买&#xff0c;续费不涨价&#xff0c;续费也是99元&#xff0c;配置为轻量2核2G4M、50GB SSD盘、300GB月流量、4M带宽&#xff1a;优惠价格99元一年&#xff0c;续费99元&#xff0c;官方活动页面 txybk.com/g…

美洲狮优化算法(Puma Optimizar Algorithm ,POA)求解机器人栅格地图最短路径规划(提供MATLAB代码)

一、美洲狮优化算法 美洲狮优化算法&#xff08;Puma Optimizar Algorithm &#xff0c;POA&#xff09;由Benyamin Abdollahzadeh等人于2024年提出&#xff0c;其灵感来自美洲狮的智慧和生活。在该算法中&#xff0c;在探索和开发的每个阶段都提出了独特而强大的机制&#xf…

【JavaSE】抽象类与接口

Object 类 类 java.lang.Object是类层次结构的根类&#xff0c;即所有类的父类。 除Object类之外的任何一个Java类&#xff0c;全部直接或间接的继承于Object类。由此&#xff0c;Object类也被称为根父类。Object类中声明的成员具有通用性&#xff0c;并且Object类中没有声明…

Linux 理解进程

目录 一、基本概念 二、描述进程-PCB 1、task_struct-PCB的一种 2、task_ struct内容分类 三、组织进程 四、查看进程 1、ps指令 2、top命令 3、/proc文件系统 4、在/proc文件中查看指定进程 5、进程的工作目录 五、通过系统调用获取进程标示符 1、getpid()/get…

消息队列 MQ

文章目录 1. MQ 相关概念1.1 什么是 MQ1.2 为什么要用 MQ1.3 MQ 分类1.4 MQ 的选择 1. MQ 相关概念 1.1 什么是 MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是 message 而已&#x…

选修-单片机作业第1/2次

第一次作业 第二次作业 1、51 系列单片机片内由哪几个部分组成&#xff1f;各个部件的最主要功能是什么&#xff1f; 51系列单片机的内部主要由以下几个部分组成&#xff0c;每个部件的主要功能如下&#xff1a; 1. **中央处理器&#xff08;CPU&#xff09;**&#xff1a;这是…

uniapp隐藏状态栏并强制横屏

uniapp隐藏状态栏并强制横屏 1.manifest.json中&#xff1a; "screenOrientation": ["landscape-primary", //可选&#xff0c;字符串类型&#xff0c;支持横屏"landscape-secondary" //可选&#xff0c;字符串类型&#xff0c;支持反向横屏]…

算法 环形数组是否存在循环 力扣执行速度击败100%

目录 题目 leetcode 457 求解思路 代码 结果 题目 leetcode 457 存在一个不含 0 的 环形 数组 nums &#xff0c;每个 nums[i] 都表示位于下标 i 的角色应该向前或向后移动的下标个数&#xff1a; 如果 nums[i] 是正数&#xff0c;向前&#xff08;下标递增方向&#xff0…

每日一题 — 三数之和

15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 双指针思想先给数组排序然后固定一个数、再设left、right指针&#xff0c;nums[left] nums[right] -nums[a]大于的话right--&#xff0c;小于的话left每次处理完left、right之后需要判断去重i也需要判…

计算机网络(五)

网络层 网络层的主要目的是实现网络互连&#xff0c;进而实现数据包在各网络之间的传输。 要实现网络层&#xff0c;主要解决三个问题&#xff1a; ①网络层向运输层提供怎样的服务&#xff1f;&#xff08;“可靠传输“、”不可靠传输“&#xff09; ②网络层寻址 ③路由选择…

乡村治理深度解析:策略、挑战与解决方案

毋庸置疑&#xff0c;在今天这个崭新的时代&#xff0c;乡村治理的过程已然向我们发出了挑战。为了迎难而上&#xff0c;我们必须摒弃陈旧观念&#xff0c;勇敢迎接并大胆尝试探索与实践新的思路&#xff01;为了达到这一宏伟目标&#xff0c;我们需要首先廓清如下关键概念&…

第九个实验:一维数组和二维字符串数组的输入而输出

实验内容: 新建一维数组 新建二维字符串数组 输入内容,运行结果,在输出界面中显示输入的内容 第一步:新建项目 第二步:编程 添加一个INT数控件和字符串控件 修改控件: 复制前面板控件

Linux 之九:CentOS 上 Tomcat 安装、SpringBoot 项目打包和部署

安装 Tomcat 下载 a. 方式一&#xff1a;可以在windows 真机上下载后&#xff0c;再上传到服务器 b. 方式二&#xff1a;可以在服务器端使用 wget 下载命令来下载 登录官网https://tomcat.apache.org/download-90.cgi&#xff0c;选择 linux 版本 右键&#xff0c;获取下载链接…

有点炫酷有点diao的免费wordpress模板主题

这是一款经典的免费wordpress主题&#xff0c;被广泛应用于多个行业的网站。 https://www.wpniu.com/themes/189.html

Vue 监听器:让你的应用实时响应变化

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Python 一步一步教你用pyglet制作汉诺塔游戏

目录 汉诺塔游戏 1. 抓取颜色 2. 绘制圆盘 3. 九层汉塔 4. 绘制塔架 5. 叠加圆盘 6. 游戏框架 汉诺塔游戏 汉诺塔&#xff08;Tower of Hanoi&#xff09;&#xff0c;是一个源于印度古老传说的益智玩具。这个传说讲述了大梵天创造世界的时候&#xff0c;他做了三根金刚…

【刷题】Leetcode 415 字符串相加 和 34 字符串相乘

刷题 Leetcode 415 字符串相加题目描述 思路一&#xff08;模拟大法版&#xff01;&#xff01;&#xff01;&#xff09;Leetcode 34 字符串相乘题目描述 思路一&#xff08;模拟大法版&#xff09;Thanks♪(&#xff65;ω&#xff65;)&#xff89;谢谢阅读&#xff01;&…

Angular基础---HelloWorld---Day3

文章目录 0.ng-model 的几种不同的class属性1.ng-model 的引用与属性的调用2.表单验证&#xff1a; (模版引用变量、ngModel 、ngif一起使用&#xff09;3.根据class属性的值ng-invalid &#xff0c;设置动态变化的样式 0.ng-model 的几种不同的class属性 引用ng-model 元素的c…