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

算法训练day29Leetcode491递增子序列46全排列47全排列Ⅱ

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

题目分析

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

所以不能使用之前的去重逻辑!同一父节点下的同层上使用过的元素就不能再使用了

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

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

acm模式代码

#include <iostream>
#include <vector>
#include <unordered_set>class Solution {
private:std::vector<std::vector<int>> result; // 用于存储所有递增子序列的结果集std::vector<int> path; // 用于在递归中构建当前递增子序列的路径// 回溯法主体函数void backtracking(std::vector<int>& nums, int startIndex) {// 如果路径长度大于1,将其加入结果集if (path.size() > 1) {result.push_back(path);// 注意这里不要加return,因为要取树上的所有节点}std::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:// 公有函数,调用此函数开始寻找所有递增子序列std::vector<std::vector<int>> findSubsequences(std::vector<int>& nums) {result.clear(); // 清空上一次的结果path.clear(); // 清空路径backtracking(nums, 0); // 从第一个元素开始递归return result; // 返回结果集}
};int main() {Solution solution;std::vector<int> nums = {4, 6, 7, 7}; // 示例数组auto subsequences = solution.findSubsequences(nums);std::cout << "Found " << subsequences.size() << " increasing subsequences:" << std::endl;for (const auto& seq : subsequences) {for (int num : seq) {std::cout << num << " ";}std::cout << std::endl;}return 0;
}

46 全排列

题目描述

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同

题目分析

首先排列是有序的,也就是说 [1,2] 和 [2,1] 是两个集合,这和之前分析的子集以及组合所不同的地方

可以看出元素1在[1,2]中已经使用过了,但是在[2,1]中还要在使用一次1,所以处理排列问题就不用使用startIndex了。

acm模式代码

#include <iostream>
#include <vector>class Solution {
private:std::vector<std::vector<int>> result; // 用于存储所有可能的排列结果std::vector<int> path; // 临时存储一个排列结果// 回溯法函数void backtracking(std::vector<int> &nums, std::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; // 重置当前数字的使用状态}return;}
public:// 主函数,返回给定数组的所有排列组合std::vector<std::vector<int>> permute(std::vector<int>& nums) {std::vector<bool> used(nums.size(), false); // 初始化所有数字未被使用result.clear(); // 清空结果集path.clear(); // 清空当前路径backtracking(nums, used); // 开始回溯搜索return result; // 返回所有排列组合的结果集}
};int main() {Solution sol;std::vector<int> nums = {1, 2, 3}; // 示例数组std::vector<std::vector<int>> result = sol.permute(nums); // 获取所有排列// 打印所有排列for (const auto &path : result) {for (const int num : path) {std::cout << num << " ";}std::cout << std::endl;}return 0;
}

输出

1 2 3 
1 3 2 
2 1 3
2 3 1
3 1 2
3 2 1

47全排列Ⅱ

题目描述

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],[1,2,1],[2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10

题目分析

去重最为关键的代码为:

if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {continue;
}

对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高!

acm模式代码

#include <iostream>
#include <vector>
#include <algorithm> // 引入算法头文件用于排序class Solution {
private:std::vector<std::vector<int>> result; // 存储最终的排列结果std::vector<int> path; // 临时存储当前排列的路径// 回溯法函数,用于递归生成排列void backtracking(std::vector<int> &nums, std::vector<bool>& used) {// 如果当前路径长度等于原数组长度,说明找到了一个完整排列if (path.size() == nums.size()) {result.push_back(path); // 将当前路径添加到结果集中return; // 回溯}for (int i = 0; i < nums.size(); i++) {// 跳过已使用的元素或同一层级中的重复元素if (used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i -1])) {continue;}used[i] = true; // 标记当前元素为已使用path.push_back(nums[i]); // 将当前元素添加到路径中backtracking(nums, used); // 递归调用继续构建路径path.pop_back(); // 回溯,移除路径中的最后一个元素used[i] = false; // 重置当前元素为未使用}}
public:// 公共接口,返回给定数组的所有独特排列std::vector<std::vector<int>> permuteUnique(std::vector<int>& nums) {std::sort(nums.begin(), nums.end()); // 对数组进行排序,以便有效地跳过重复元素std::vector<bool> used(nums.size(), false); // 初始化使用标记数组result.clear(); // 清空结果集path.clear(); // 清空当前路径backtracking(nums, used); // 开始回溯搜索return result; // 返回结果集}
};int main() {Solution sol;std::vector<int> nums = {1, 1, 2, 3}; // 示例输入std::vector<std::vector<int>> result = sol.permuteUnique(nums); // 获取所有独特的排列// 打印所有排列for (const auto &path : result) {for (const int num : path) {std::cout << num << " ";}std::cout << std::endl;}return 0;
}

输出

1 1 2 3 
1 1 3 2
1 2 1 3
1 2 3 1
1 3 1 2
1 3 2 1
2 1 1 3
2 1 3 1
2 3 1 1
3 1 1 2
3 1 2 1
3 2 1 1

相关文章:

算法训练day29Leetcode491递增子序列46全排列47全排列Ⅱ

491 递增子序列 题目描述 给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以视作递增序列的一…...

内网穿透与搭建私人服务器

前言 内网穿透是一种技术&#xff0c;允许用户从外部网络访问内部私有网络中的服务器或设备。这对于想要从任何地方访问家中或办公室内部网络资源的用户非常有用。以下是为初学者准备的关于如何实现内网穿透以及搭建自己的私人服务器的详细指南。 在这个数字化时代&#xff0c;…...

交大论文下载器

原作者地址&#xff1a; https://github.com/olixu/SJTU_Thesis_Crawler 问题&#xff1a; http://thesis.lib.sjtu.edu.cn/的学位论文下载系统&#xff0c;该版权保护系统用起来很不方便&#xff0c;加载起来非常慢&#xff0c;所以该下载器实现将网页上的每一页的图片合并…...

全栈笔记_浏览器扩展篇(manifest.json文件介绍)

manifest.json介绍 是web扩展技术必不可少的插件配置文件,放在根目录作用: 指定插件的基本信息 name:名称manifest_version:manifest.json文件的版本号,可以写2或3version:版本description:描述定义插件的行为: browser_action:添加一个操作按钮到浏览器工具栏,点击按…...

蓝桥杯每日一题(python)

##斐波那契数列的应用 --- 题目斐波那契 题目&#xff1a; 如果数组 A (a0, a1, , an−1) 满足以下条件&#xff0c;就说它是一个斐波那契数组&#xff1a; 1. n ≥ 2&#xff1b; 2. a0 a1&#xff1b; 3. 对于所有的 i(i ≥ 2)&#xff0c;都满足 ai ai−1 ai−2…...

【Vue】工程化开发脚手架Vue CLI

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;Vue⛺️稳重求进&#xff0c;晒太阳 工程化开发&脚手架Vue CLI 基本介绍 Vue Cli是Vue官方提供的一个全局命令工具 可以帮助我们快速创建一个开发Vue项目的标准化基础架子【集成了we…...

嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第三天-ARM Linux ADC和触摸屏开发 (物联技术666)

链接&#xff1a;https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd1688 提取码&#xff1a;1688 教学内容&#xff1a; 1、ADC S3C2440的A/D转换器包含一个8通道的模拟输入转换器&#xff0c;可以将模拟输入信号转换成10位数字编码。 在A/D转换时钟频率为2.5MHz时&…...

LeetCode “AddressSanitizer:heat-use-after-free on address“问题解决方法

heat-use-after-free &#xff1a; 访问堆上已经被释放的内存地址 现象&#xff1a;同样代码在LeetCode上报错&#xff0c;但是自己在IDE手动打印并不会报错 个人猜测&#xff0c;这个bug可能来源于LeetCode后台输出打印链表的代码逻辑问题。 问题描述 题目来自LeetCode的8…...

幸运彩票

L1-6 幸运彩票 分数 15 作者 陈越 单位 浙江大学 彩票的号码有 6 位数字&#xff0c;若一张彩票的前 3 位上的数之和等于后 3 位上的数之和&#xff0c;则称这张彩票是幸运的。本题就请你判断…...

搭建yum仓库服务器

安装 1.安装linux 1.1安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 1.2下载 cd /opt/nginx wget http://nginx.org/download/nginx-1.25.3.tar.gz 1.3解压 tar -xvf nginx-1.25.3.tar.gz 1.4配置 cd nginx-1.25.3 ./configure --pre…...

贪心算法练习day1

练习1--翻硬币 1&#xff09;题目及要求 2&#xff09;解题思路 输入的是字符串&#xff0c;要想将两组字符串进行一一对比&#xff0c;需要将字符串转换成字符数组&#xff0c;再使用for循环依次遍历字符数组&#xff0c;进行比对。 输入两行字符串&#xff0c;转换成两个字…...

[VulnHub靶机渗透] WestWild 1.1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…...

如何使用 ControlValueAccessor 在 Angular 中创建自定义表单控件

简介 在 Angular 中创建表单时&#xff0c;有时您希望拥有一个不是标准文本输入、选择或复选框的输入。通过实现 ControlValueAccessor 接口并将组件注册为 NG_VALUE_ACCESSOR&#xff0c;您可以将自定义表单控件无缝地集成到模板驱动或响应式表单中&#xff0c;就像它是一个原…...

视频讲解:优化柱状图

你好&#xff0c;我是郭震 AI数据可视化 第三集&#xff1a;美化柱状图&#xff0c;完整视频如下所示&#xff1a; 美化后效果前后对比&#xff0c;前&#xff1a; 后&#xff1a; 附完整案例源码&#xff1a; util.py文件 import platformdef get_os():os_name platform.syst…...

OpenAI宣布ChatGPT新增记忆功能;谷歌AI助理Gemini应用登陆多地区

&#x1f989; AI新闻 &#x1f680; OpenAI宣布ChatGPT新增记忆功能&#xff0c;可以自由控制内存&#xff0c;提供个性化聊天和长期追踪服务 摘要&#xff1a;ChatGPT新增的记忆功能可以帮助AI模型记住用户的提问内容&#xff0c;并且可以自由控制其内存。这意味着用户不必…...

Solidworks:平面草图练习

继续练习平面草图&#xff0c;感觉基本入门了。...

React18原理: 渲染与更新时的重点关注事项

概述 react 在渲染过程中要做很多事情&#xff0c;所以不可能直接通过初始元素直接渲染还需要一个东西&#xff0c;就是虚拟节点&#xff0c;暂不涉及React Fiber的概念&#xff0c;将vDom树和Fiber 树统称为虚拟节点有了初始元素后&#xff0c;React 就会根据初始元素和其他可…...

嵌入式I2C 信号线为何加上拉电阻(图文并茂)

IIC 是一个两线串行通信总线&#xff0c;包含一个 SCL 信号和 SDA 信号&#xff0c;SCL 是时钟信号&#xff0c;从主设备发出&#xff0c;SDA 是数据信号&#xff0c;是一个双向的&#xff0c;设备发送数据和接收数据都是通过 SDA 信号。 在设计 IIC 信号电路的时候我们会在 SC…...

Vite 5.0 正式发布

11 月 16 日&#xff0c;Vite 5.0 正式发布&#xff0c;这是 Vite 道路上的又一个重要里程碑&#xff01;Vite 现在使用 Rollup 4&#xff0c;这已经代表了构建性能的大幅提升。此外&#xff0c;还有一些新的选项可以改善开发服务器性能。 Vite 4 发布于近一年前&#xff0c;它…...

嵌入式STM32 单片机 GPIO 的工作原理详解

STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称&#xff0c;是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接&#xff0c;可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子&#xff0c;该芯片共有 144 脚芯片&#xff0c…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

开疆智能Ethernet/IP转Modbus网关连接鸣志步进电机驱动器配置案例

在工业自动化控制系统中&#xff0c;常常会遇到不同品牌和通信协议的设备需要协同工作的情况。本案例中&#xff0c;客户现场采用了 罗克韦尔PLC&#xff0c;但需要控制的变频器仅支持 ModbusRTU 协议。为了实现PLC 对变频器的有效控制与监控&#xff0c;引入了开疆智能Etherne…...

【设计模式】1.简单工厂、工厂、抽象工厂模式

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 以下是 简单工厂模式、工厂方法模式 和 抽象工厂模式 的 Python 实现与对比&#xff0c;结合代码示例和实际应用场景说明&#xff1a; 1. 简单工厂模式&a…...