算法训练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

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

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

相关文章

【自我介绍】计算机软件工程人工智能研究生复试资料整理

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 自我介绍 英文 自我介绍 英文 第一段: Good afternoon, dear professors, thank you for the chance to introduce myself. My name is Yan Zhen Xing, and I a…

已解决AttributeError: ‘str‘ object has no attribute ‘decode‘异常的正确解决方法,亲测有效!!!

已解决AttributeError: str object has no attribute decode异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 文章目录 问题分析 报错原因 解决思路 解决方法 总结 当你在Python编程时碰到“AttributeError: str object has no attribute d…

UVA1449 Dominating Patterns 题解

UVA1449 Dominating Patterns 题解 板子题诶。 解法 AC 自动机模板题&#xff0c;因为数据范围比较小&#xff0c;所以不加拓扑排序优化建图即可通过本题。这里简单介绍一下拓扑排序优化建图。 在查找时&#xff0c;每次都暴力的条 f a i l fail fail 指针是很消耗时间的&…

vue-进阶语法(四)

目录 v-model原理 v-model应用于组件 sync修饰符 ref 和 $refs&#xff08;重点&#xff09; $nextTick v-model原理 原理&#xff1a;v-model本质上是一个语法糖。例如应用在输入框上&#xff0c;就是 value属性 和 input事件 的合写。 作用&#xff1a;提供数据的双向…

压缩PDF的大小-Adobe Acrobat Pro

经常遇到上传的pdf太大&#xff0c;无法成功上传。 今天找到一个方法&#xff1a; 打开Adobe Acrobat Pro软件 → 文件 → 另存为其他&#xff08;H&#xff09;... →缩小大小的PDF 版本选择 4.0 最低的版本。 文件由9M变为1.5M。

Codeforces Round 924 (Div. 2) B - D

B. Equalize 题目&#xff1a; 思路&#xff1a;首先排序然后去重&#xff08;可以用set来去重&#xff09;&#xff0c;我们可以肯定的是&#xff0c;如果连续k个数最大值最小值的差小于等于n的话&#xff0c;那么这个长度为k的区间就符合答案要求&#xff0c;那么k就和答案…

###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 目录 一. 延时函数的生成 1.通过延时计算器得到延时函数 2.可赋值改变…

Linux释放内存

free -m是Linux上查看内存的指令&#xff0c;其中-m是以兆&#xff08;MB&#xff09;为单位&#xff0c;如果不加则以KB为单位。 如下图表示&#xff0c;&#xff08;total&#xff09;总物理内存是809MB&#xff0c;&#xff08;used&#xff09;已使用167MB&#xff0c;&…

【AI视野·今日NLP 自然语言处理论文速览 第七十九期】Thu, 18 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 18 Jan 2024 Totally 35 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deciphering Textual Authenticity: A Generalized Strategy through the Lens of Large Language Semantics …

使用STM32CubeMX配置和优化DMA传输

STM32CubeMX是STMicroelectronics提供的一款图形化配置工具&#xff0c;可以帮助开发人员对STM32微控制器进行初始化配置和代码生成。在本文中&#xff0c;我们将介绍如何使用STM32CubeMX来配置和优化DMA传输&#xff0c;并提供一个简单的示例代码来演示DMA的配置和使用。 ✅作…

【Py/Java/C++三种语言详解】LeetCode每日一题240215【二叉树BFS】LeetCode107、二叉树的层序遍历II

有LeetCode交流群/华为OD考试扣扣交流群可加&#xff1a;948025485 可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1336了解算法冲刺训练 文章目录 题目链接题目描述解题思路DFS和BFS异同用队列维护的BFS 代码PythonJavaC时空复杂度 相关习题华为OD算法/大…

寒假学习记录13:JS对象

目录 对象转数组 对象双值转数组 Object.entries() &#xff08;转为二维数组&#xff09;&#xff08;属性的值和键&#xff09; 对象右值转数组 Object.values() &#xff08;属性的值&#xff09; 对象左值转数组 Object.keys() (属性的键) 对象左值转…

计算机视觉基础:获取图像的ROI

在图像处理过程中&#xff0c;我们可能会对图像的某一个特定区域感兴趣&#xff0c;该区域被称为感兴趣区域&#xff08;Region of Interest&#xff0c;ROI&#xff09;。在设定感兴趣区域ROI后&#xff0c;就可以对该区域进行整体操作。 Python实现代码如下&#xff1a; # -…

怎样学习Windows下命令行编写

第一&#xff1a;Windows下命令行指的是cmd和powershell命令行编写 第二&#xff1a;必须要用好help或/?命令&#xff0c;这个命令是最基本的也是最常用的命令列表和语法查看命令 第三&#xff1a;cmd命令使用help查看命令列表或“一串带参数的命令 /?"&#xff08;不…

[职场] 花园管家是做什么的 #笔记#学习方法

花园管家是做什么的 一、工作内容职责&#xff1a; 1.管理花园内的活动和工作&#xff0c;协调各方资源&#xff0c;确保活动的顺利进行&#xff1b; 2.提供优质的客户服务和接待工作&#xff0c;解决客户问题&#xff0c;处理投诉&#xff0c;提高客户满意度&#xff1b; …

(03)Hive的相关概念——分区表、分桶表

目录 一、Hive分区表 1.1 分区表的概念 1.2 分区表的创建 1.3 分区表数据加载及查询 1.3.1 静态分区 1.3.2 动态分区 1.4 分区表的本质及使用 1.5 分区表的注意事项 1.6 多重分区表 二、Hive分桶表 2.1 分桶表的概念 2.2 分桶表的创建 2.3 分桶表的数据加载 2.4 …

C++ 基础算法 前缀和

输入一个长度为 n 的整数序列。 接下来再输入 m 个询问&#xff0c;每个询问输入一对 l,r 。 对于每个询问&#xff0c;输出原序列中从第 l 个数到第 r 个数的和。 输入格式 第一行包含两个整数 n 和 m 。 第二行包含 n 个整数&#xff0c;表示整数数列。 接下来 m 行&…

操作系统(14)----文件系统的结构

目录 一.文件系统的层次结构 1.用户接口&#xff1a; 2.文件目录系统&#xff1a; 3.存取控制模块&#xff1a; 4.逻辑文件系统与文件信息缓冲区&#xff1a; 5.物理文件系统&#xff1a; 二.文件系统的全局结构 1.文件系统在外存中的结构 &#xff08;1&#xff09;物…

Mermaid绘制UML图教程

Mermaid 是一种轻量级的图形描述语言&#xff0c;用于绘制流程图、时序图、甘特图等各种图表。它采用简单的文本语法&#xff0c;使得用户能够快速绘制各种复杂图表&#xff0c;而无需深入学习图形绘制工具。 一、安装Mermaid Mermaid 可以在浏览器中直接使用&#xff0c;也可…

剑指offer——数值的整数次方

目录 1. 题目描述2. 一般思路2.1 有问题的思路2.2 全面但不高效的思路2.3 面试小提示 3. 全面又高效的思路 1. 题目描述 题目:实现函数 double Power(double base,int exponent)&#xff0c;求base 的exponent 次方。不得使用库函数&#xff0c;同时不需要考虑大数问题 2. 一般…