Leetcode算法训练日记 | day29

一、递增子序列

1.题目

Leetcode:第 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]]

2.解题思路

使用回溯算法来解决序列问题。findSubsequences 函数负责初始化并开始回溯过程。backtracking 函数是回溯算法的核心,它尝试在每个位置选择或不选择当前的元素,并递归地继续处理后续的元素。通过这种方式,backtracking 函数能够找到所有可能的子序列。使用一个大小为 201 的数组 used 来标记元素是否已经被使用过。这是因为数组 nums 中的元素值被假定为在 0 到 200 之间。如果 nums 中的元素值超出这个范围,需要相应地调整 used 数组的大小。此外,used 数组的索引是 nums[i] + 100,这是为了将 nums 中的元素值映射到 used 数组的索引范围内。

3.实现代码

#include <iostream>
#include <vector>
using namespace std;class Solution {
public:vector<vector<int>> result;// 定义一个二维整数数组用于存储所有子序列的结果vector<int> path; // 定义一个一维整数数组用于存储当前子序列// 定义 backtracking 函数,用于实现回溯算法void backtracking(vector<int>& nums, int startIdex) {// 如果当前子序列的长度大于1,将其添加到结果集中if (path.size() > 1) {result.push_back(path);}// 定义一个数组用于标记数组中每个元素是否已经被使用过int used[201] = { 0 };// 遍历 nums 数组,从 startIdex 开始for (int i = startIdex; i < nums.size(); i++) {// 如果当前元素已经被添加到路径中,或者当前元素小于路径中最后一个元素,跳过if ((!path.empty() && nums[i] < path.back()) || used[nums[i] + 100] == 1) {continue;}used[nums[i] + 100] = 1; // 标记当前元素为已使用path.push_back(nums[i]);// 将当前元素添加到路径中 backtracking(nums, i + 1);// 递归调用 backtracking 函数,以当前元素的下一个元素作为新的起始索引path.pop_back();// 回溯:从路径中移除最后一个元素}}// 定义 findSubsequences 函数,用于生成所有子序列vector<vector<int>> findSubsequences(vector<int>& nums) {// 清空结果集和路径,为生成新的子序列做准备result.clear();path.clear();backtracking(nums, 0); // 调用 backtracking 函数,开始回溯过程return result;// 返回结果集 result}
};//测试
int main()
{Solution p;vector<vector<int>> result;vector<int>nums = { 4,6,7,7 };result = p.findSubsequences(nums);cout << "所有的组合有:" << endl;for (auto& ans : result) {cout << "[";for (auto& i : ans) {cout << i << " ";}cout << "]" << endl;}cout << endl;return 0;
}

 

二、全排列

1.题目

Leetcode:第 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]]
2.解题思路

使用回溯算法来解决排列问题。permute 函数负责初始化并开始回溯过程。backtracking 函数是回溯算法的核心,它尝试在每个位置放置数组中的每个元素,并递归地继续处理后续的元素。通过这种方式,backtracking 函数能够找到所有可能的排列。used 向量是一个辅助工具,用于确保数组中的每个元素在当前排列中只出现一次,并允许回溯算法在必要时回退到之前的步骤,以探索其他可能的排列。这种方法可以生成包括重复元素在内的所有排列,如果数组中有重复元素,结果集中可能会出现重复的排列。如果需要排除重复的排列,可以增加额外的逻辑来检查新排列是否已经存在于结果集中。

3.实现代码
#include <iostream>
#include <vector>
using namespace std;class Solution {
public:vector<vector<int>> result; // 定义一个二维整数数组用于存储所有排列的结果vector<int> path;// 定义一个一维整数数组用于存储当前排列// 定义 backtracking 函数,用于实现回溯算法void backtracking(vector<int>& nums, 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);// 递归调用 backtracking 函数,继续寻找下一个元素的排列path.pop_back();// 回溯:从当前排列中移除最后一个元素,尝试其他可能性used[i] = false;// 重置该元素为未使用状态,以便其他排列可以使用}}// 定义 permute 函数,用于生成所有排列vector<vector<int>> permute(vector<int>& nums) {// 清空结果集和当前排列,为生成新的排列做准备result.clear();path.clear();vector<bool> used(nums.size(), false);// 创建一个与 nums 数组大小相同的布尔向量,用于跟踪每个元素是否已使用backtracking(nums, used); // 调用 backtracking 函数,开始回溯过程return result;// 返回结果集 result,其中包含了所有可能的排列}
};//测试
int main()
{Solution p;vector<vector<int>> result;vector<int>nums = { 1,2,3 };result = p.permute(nums);cout << "所有的组合有:" << endl;for (auto& ans : result) {cout << "[";for (auto& i : ans) {cout << i << " ";}cout << "]" << endl;}cout << endl;return 0;
}

 

三、全排列Ⅱ

1.题目

Leetcode:第 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]]
2.解题思路

使用回溯算法来解决排列问题。在这个类中,permuteUnique 函数首先清空结果集和当前路径,然后对输入数组 nums 进行排序。排序后,它创建一个布尔向量 used 来跟踪每个元素是否已被使用,并调用 backtracking 函数开始生成排列。backtracking 函数是回溯算法的核心,它尝试在每个位置放置数组中的每个元素,并递归地继续处理后续的元素。通过检查 i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false 来跳过与前一个未使用的元素相同的元素,从而避免生成重复的排列。这种方法可以生成数组的所有唯一排列,即使数组中有重复元素,结果集中也不会出现重复的排列。

3.实现代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;class Solution {
public: vector<vector<int>> result;// 定义一个二维整数数组用于存储所有唯一排列的结果vector<int> path;// 定义一个一维整数数组用于存储当前正在构建的排列// 定义 backtracking 函数,用于实现回溯算法生成唯一排列void backtracking(vector<int>& nums, vector<bool>& used) {// 当前路径的长度等于原始数组的长度时,说明找到了一个完整的排列if (path.size() == nums.size()) {// 将当前路径添加到结果集中 result.push_back(path);    return;// 返回继续搜索其他排列}// 遍历数组中的每个元素for (int i = 0; i < nums.size(); i++) {// 如果当前元素与前一个元素相同,并且前一个元素未被使用过,则跳过当前元素以避免重复if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) {continue;}// 如果当前元素未被使用if (used[i] == false) {used[i] = true;// 标记当前元素为已使用path.push_back(nums[i]);// 将当前元素添加到路径中backtracking(nums, used);// 递归调用 backtracking 函数,继续寻找下一个元素的排列path.pop_back();// 回溯:从路径中移除最后一个元素,回退到上一步used[i] = false;// 重置当前元素为未使用状态,以便可以重新使用}}}// 定义 permuteUnique 函数,用于生成所有唯一排列vector<vector<int>> permuteUnique(vector<int>& nums) {// 清空结果集和当前路径,为生成新的排列做准备result.clear();path.clear();sort(nums.begin(), nums.end());// 对输入数组进行排序,这样相同的元素会相邻,有助于避免重复排列vector<bool> used(nums.size(), false);// 创建一个布尔数组,用于跟踪数组中的每个元素是否已被使用 backtracking(nums, used);// 调用 backtracking 函数,开始回溯过程生成排列return result;// 返回包含所有唯一排列的结果集}
};//测试
int main()
{Solution p;vector<vector<int>> result;vector<int>nums = { 1,2,2 };result = p.permuteUnique(nums);cout << "所有的组合有:" << endl;for (auto& ans : result) {cout << "[";for (auto& i : ans) {cout << i << " ";}cout << "]" << endl;}cout << endl;return 0;
}

 ps:以上皆是本人在探索算法旅途中的浅薄见解,诚挚地希望得到各位的宝贵意见与悉心指导,若有不足或谬误之处,还请多多指教。

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

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

相关文章

“低价竞争”仍在继续,分期免息成商家新武器

近日&#xff0c;在京东618商家生态伙伴大会上&#xff0c;京东推出各项政策&#xff0c;尽全力让所有合作伙伴赢在京东618、赢在京东。京东金融也将在618大促期间&#xff0c;为各位商家带来极具竞争力的金融产品和大促政策。 举例来说&#xff0c;大促期间&#xff0c;“京东…

基于SSM+Jsp+Mysql的文物管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

js高级 笔记02

目录 01 object提供的一些静态方法 02 词法作用域 03 作用域链 04 arguments的使用 05 开启严格模式 06 高阶函数 07 闭包 01 object提供的一些静态方法 Object.create() 对象继承 Object.assign(对象1,对象2) 对象合并 可以将对象2 里面的可枚举属性和自身的属性合并到…

Matlab r2023b Simulink 给子系统添加封面

写这篇记录的原因是&#xff0c;r2023b版本里改动了自定义封面的界面&#xff0c;而我是一个新手小白&#xff0c;零基础&#xff0c;探索一天之后发现实现方法。最终效果如图&#xff1a; 步骤1&#xff1a;打开软件&#xff0c;点击Simulink&#xff0c;再打开含有子系统的工…

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题7

【题目】【信息安全管理与评估】2022年国赛高职组“信息安全管理与评估”赛项样题7 信息安全管理与评估 网络系统管理 网络搭建与应用 云计算 软件测试 移动应用开发 任务书&#xff0c;赛题&#xff0c;解析等资料&#xff0c;知识点培训服务 添加博主wx&#xff1a;liuliu548…

SpringSecurity源码4

SecurityContext.class 当前线程关联的最小安全信息&#xff0c;提供Authentication的get/set方法 SecurityContextHolder.class SecurityContext的持有器 // 全部委托给策略类public static void setContext(SecurityContext context) {strategy.setContext(context);}public …

FFmpeg: 自实现ijkplayer播放器--03UI界面设计

文章目录 UI设计流程图UI设计界面点击播放功能实现 UI设计流程图 UI设计界面 主界面 控制条 播放列表 画面显示 标题栏 设置界面 提示框 点击播放功能实现 槽函数实现&#xff1a; connect(ui->ctrlBarWind, &CtrlBar::SigPlayOrPause, this, &Main…

[渗透测试学习] TwoMillion-HackTheBox

TwoMillion-HackTheBox 信息搜集 nmap扫描一下 nmap -sV -v 10.10.11.221扫描结果 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.1 (Ubuntu Linux; protocol 2.0) 80/tcp open http nginx 3851/tcp f…

4.18作业

顺序栈&#xff1a; #include "seq_stack.h" seq_p creat_stack() //从堆区申请顺序栈的空间 {seq_p S(seq_p)malloc(sizeof(seq_stack));if(SNULL){printf("空间申请失败\n");return NULL;}bzero(S->data,sizeof(S->data));S->top-1;return S; …

多任务学习,在共享层,究竟在共享什么?

在多任务学习中&#xff0c;共享层所共享的主要是网络结构和参数。具体来说&#xff0c;当多个任务在共享层进行参数硬共享时&#xff0c;它们使用的是相同的网络结构&#xff08;例如三层全连接神经网络&#xff09;&#xff0c;并且这些网络层的权重&#xff08;weights&…

深入解析Nacos配置中心的动态配置更新技术

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在微服务架构中&#xff0c;配置管理变得尤为关键。Nacos&#xff0c;作为一个开源的、易于使用的、功能丰富的平台&#xff0c;为…

【MATLAB源码-第28期】基于matlab的16QAM定时同步仿真,采用gardner算法,Costa锁相环。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 正交幅度调制&#xff08;QAM&#xff0c;Quadrature Amplitude Modulation&#xff09;是一种在两个正交载波上进行幅度调制的调制方式。这两个载波通常是相位差为90度&#xff08;π/2&#xff09;的正弦波&#xff0c;因此…

02 - Git 之命令 + 删除 + 版本控制 + 分支 + 标签 + 忽略文件 + 版本号

1 Git相关概念 1.1 以下所谈三个区&#xff0c;文件并不只是简单地在三个区转移&#xff0c;而是以复制副本的方式转移 使用 Git 管理的项目&#xff0c;拥有三个区域&#xff0c;分别是 Working area工作区&#xff08;亦称为 工作树Working Tree&#xff09;、stage area …

[渗透测试学习] Monitored-HackTheBox

Monitored-HackTheBox 信息搜集 nmap扫描一下端口 nmap -sV -sC -v --min-rate 1000 10.10.11.248扫描结果如下 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u3 (protocol 2.0) 80/tcp open http Apache httpd …

视觉位置识别与多模态导航规划

前言 机器人感知决策是机器人移动的前提&#xff0c;机器人需要对周围环境实现理解&#xff0c;而周围环境通常由静态环境与动态环境构成。机器人在初始状态或者重启时需要确定当前所处的位置&#xff0c;然后根据用户的指令或意图&#xff0c;开展相应移动或抓取操作。通过视觉…

【分治】Leetcode 排序数组

题目讲解 912. 排序数组 算法讲解 我们这里使用三指针&#xff0c;将数组分成三块&#xff1a;<key 和 key 和 >key,如果当前指针指向的数字<key&#xff0c;我们就swap(nums[left]), nums[i] 。如果当前的数字key &#xff0c;就让i。如果当前的数字>key&…

geolife笔记/python笔记:trackintel.io.read_geolife

此函数解析 geolife_path 目录中可用的所有 geolife 数据 trackintel.io.read_geolife(geolife_path, print_progressFalse) 参数&#xff1a; geolife_path (str) 包含 geolife 数据的目录路径 print_progress (Bool, 默认为 False)如果设置为 True&#xff0c;则显示每个…

退出 beeline

退出 beeline 的命令是 !quit或 !exit 或者&#xff0c;直接来 Ctrl-D 我们下期见&#xff0c;拜拜&#xff01;

Linux 内核复合页(compound page)原理分析

源码基于&#xff1a;Linux5.15 约定&#xff1a; 芯片架构&#xff1a;ARM64内存架构&#xff1a;UMACONFIG_ARM64_VA_BITS&#xff1a;39CONFIG_ARM64_PAGE_SHIFT&#xff1a;12CONFIG_PGTABLE_LEVELS &#xff1a;3 1. 简介 复合页(Compound Page) 只是将两个或更多物理上…

【笔试强训】DFS、优先队列、滑动窗口笔试题目!

文章目录 1. 单词搜索2. 除 2 操作3. dd 爱框框 1. 单词搜索 题目链接 解题思路&#xff1a; DFS (深度优先遍历)&#xff0c;用一个 pos 记录要匹配单词 word 的位置&#xff0c;每次与 pos 进行匹配判断&#xff08;这样做的好处是不用把答案存下来&#xff09; 注意细节…