【C++11数据结构与算法】C++ 栈

C++ 栈(stack)

文章目录

  • C++ 栈(stack)
    • 栈的基本介绍
    • 栈的算法运用
      • 单调栈
        • 实战题
          • LC例题:[321. 拼接最大数](https://leetcode.cn/problems/create-maximum-number/)
          • LC例题:[316. 去除重复字母](https://leetcode.cn/problems/remove-duplicate-letters/)

栈的基本介绍

CPP API: stack

  • 一种先进后出(FILO)的数据结构

  • 定义:stack <typedef> stack_name ;

  • 我们在初始化一个stack时,其中的类型也可以为标准库类型以及自定义类型,如果想创建一个包含多元素的类型应该如下定义:

    // 括号中所用的就是
    stack<pair<TreeNode*, int>> treeStack;
    
函数描述
(constructor)该函数用于构造堆栈容器。
empty该函数用于测试堆栈是否为空。如果堆栈为空,则该函数返回true,否则返回false。
size该函数返回堆栈容器的大小,该大小是堆栈中存储的元素数量的度量。
top该函数用于访问堆栈的顶部元素。该元素起着非常重要的作用,因为所有插入和删除操作都是在顶部元素上执行的。
push该函数用于在堆栈顶部插入新元素。
pop该函数用于删除元素,堆栈中的元素从顶部删除。
emplace该函数用于在当前顶部元素上方的堆栈中插入新元素。
swap该函数用于交换引用的两个容器的内容。
relational operators非成员函数指定堆栈所需的关系运算符。
uses allocator顾名思义,非成员函数将分配器用于堆栈。
#include <iostream>
#include <stack>
using namespace std;
void newstack(stack <int> ss)
{stack <int> sg = ss;while (!sg.empty()){cout << '\t' << sg.top();sg.pop();}cout << '\n';
}
int main ()
{stack <int> newst;newst.push(55);newst.push(44);newst.push(33);newst.push(22);newst.push(11);cout << "最新的堆栈是 : ";newstack(newst);cout << "\n newst.size() : " << newst.size();cout << "\n newst.top() : " << newst.top();cout << "\n newst.pop() : ";newst.pop();newstack(newst); return 0;
}

关于push()和emplace():

  • push()函数接受一个参数,该参数是要添加到栈顶的元素的副本。

  • 当调用push()函数时,参数会被复制到栈中,即使元素是通过移动构造函数构造的也会发生复制。

  • emplace()函数接受的参数是用于构造栈顶元素的参数列表。

  • 当调用emplace()函数时,参数会被直接传递给栈顶元素的构造函数,避免了额外的复制操作。因此,emplace()通常比push()更高效。

  • 因此主要区别在于push()接受的是元素的值,而emplace()接受的是元素构造函数的参数列表。emplace()通常更灵活和高效,特别是当元素是通过移动构造函数构造时。

栈的算法运用

单调栈

栈内排序通常满足“单调递增”、“单调递减”,即栈中元素具备“单调性”

实战题
LC例题:321. 拼接最大数

在这个题目中,我们寻找数组的最大子串时,运用了单调栈的特性。但并非完全单调,以下,仅提供寻找最大子串func部分:

注意:这里的最大子串,指的是数组截选出来的子数组中元素相对位置不改变

vector<int> MaxSubNums(vector<int>& nums, int n){// 如果为空,不用遍历if (n == 0) {return {};}stack<int> resStack;int pos = 0;while (pos < nums.size()) {// 余下+当前大小 > 目标大小if ((resStack.size() + nums.size() - pos) == n) break;// 如果栈为空if (resStack.empty()) {resStack.push(nums[pos]);pos++;continue;}// 如果栈满了 且大于栈顶if (resStack.size() == n) {if (nums[pos] > resStack.top()) {resStack.pop();continue;}else {pos++;}}if (resStack.size() < n) {// 小于等于,直接pushif (nums[pos] <= resStack.top()) {resStack.push(nums[pos]);pos++;}else {resStack.pop();}}}while (resStack.size() < n && pos < nums.size()) {resStack.push(nums[pos]);pos++;}vector<int> result;while (!resStack.empty()) {result.push_back(resStack.top());resStack.pop();}std::reverse(result.begin(), result.end());return result;}
LC例题:316. 去除重复字母

题目:给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

image-20240408145007629

解法:因为要使结果为字典序最小,我们利用单调栈性质,使其从底至上为升序(非完全)

我们需要一个map(strCount)用于记录余下字符串中,某字符剩余多少

还需要一个set用于记录栈中已存在哪些元素

遍历字符串,入栈规则:

  • 首先:strCount[cur]–

1、若当前字符cur已在栈中,略过,

2、若当前字符cur未在栈中:

  1. cur > stack.top() || stack.empty() ,跳到第3步。
  2. cur < stack.top()
    1. 如果栈顶元素之后还会出现,弹出
    2. 循环上述操作,直到 栈空 或者 cur > stack.top() 或者栈顶元素在之后不再出现,结束循环
  3. 入栈,并在set中记录

遍历完字符串后,栈底到栈顶的元素拼起来就是最终答案。

class Solution
{
public:string removeDuplicateLetters(string s){// 判断该字符余下还有多少个unordered_map<char, int> strCount;// 判断栈中是否包含这个元素,如果有就不可以pushunordered_set<char> inStack;for (auto c : s){strCount[c]++;}// 单调栈,保持从栈底往上升序(非完全)stack<char> strStack;for (auto c : s){// 当前字符剩余个数减1strCount[c]--;// 栈中已有该元素,遍历下一个if (inStack.count(c) != 0)continue;// 如果当前栈不为空 且  当前元素大于栈顶元素,且栈顶元素在剩余字符中还会出现while (!strStack.empty() && c < strStack.top() && strCount[strStack.top()] > 0){inStack.erase(strStack.top());strStack.pop();}// 入栈strStack.push(c);// 记录该元素已经在栈中出现过inStack.insert(c);}string ans = "";while (!strStack.empty()){ans = strStack.top() + ans;strStack.pop();}return ans;}
};

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

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

相关文章

下决心!学点前端图形开发来提升自已

前端图形开发已成为Web开发绕不开的部分。提升自己前端图形开发能力&#xff0c;才能快点在岗位中突围。但一看到各大实战教程的学习路径就犯难了。 内容不少&#xff0c;感觉学到老也跳不出来啊。还是走回老路&#xff1f;搞个热门国外开源框架应付算了。 我简单通过对图形系…

程序猿大战Python——流程控制——if基础语句

三大基本语句 目标&#xff1a;了解三大基本语句有哪些&#xff1f; Python中有三大基本语句&#xff0c;它们支撑起了程序的业务逻辑处理。 三大基本语句有&#xff1a; &#xff08;1&#xff09;顺序语句 &#xff08;2&#xff09;分支语句 &#xff08;3&#xff09;循…

树莓派 5 AI 套件(Hailo)示例

系列文章目录 前言 欢迎访问 Hailo Raspberry Pi 5 示例库。本项目展示了在 Raspberry Pi 5 上演示 Hailo AI 处理器功能的各种示例。这些示例将帮助您开始在嵌入式设备上使用人工智能。更多信息&#xff0c;请访问 Hailo 官方网站和 Hailo 社区论坛。 一、如何设置 Raspberry…

Apple - Quartz 2D Programming Guide

本文翻译自&#xff1a;Quartz 2D Programming Guide&#xff08;更新时间&#xff1a;2017-03-21 https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html#//apple_ref/doc/uid/TP300010…

Renesas MCU之SCI_SPI接口驱动LCD

目录 概述 1 软硬件介绍 1.1 软件版本信息 1.2 ST7796-LCD 1.3 MCU IO与LCD PIN对应关系 2 FSP配置项目 2.1 配置项目参数 2.2 生成项目框架 3 代码实现 3.1 SPI的库函数 3.1.1 R_SCI_SPI_Open() 3.1.2 R_SCI_SPI_Read() 3.1.3 R_SCI_SPI_Write() 3.2 应用函数…

【全开源】Workerman在线客服系统(ThinkPHP+FastAdmin+Workerman)

Workerman在线客服系统&#xff1a;高效沟通的新选择 基于ThinkPHPFastAdminWorkerman开发的一款实时在线客服系统&#xff0c;支持多客服(不限座席)、知识库、离线留言板、离线消息、历史会话、微信小程序接入、Uni-app接入(高级授权)、用户轨迹等功能。​ &#x1f4e2; 一…

如何远程连接Linux服务器?

远程连接Linux服务器是通过网络连接到位于远程位置的Linux服务器&#xff0c;以进行服务器管理和操作。远程连接使得系统管理员可以方便地远程访问服务器&#xff0c;进行配置、维护和故障排除等操作&#xff0c;而不必亲自在服务器前工作。以下是一些常用的远程连接方法&#…

python - Pandas缺失值处理

文中所用数据集已上传,找不到的可以私聊我 学习目标 知道空值和缺失值的区别以及缺失值的影响 知道如何查看数据集缺失值情况的方法 知道缺失值处理的办法 1 NaN简介 好多数据集都含缺失数据。缺失数据有多种表现形式 数据库中&#xff0c;缺失数据表示为NULL 在某些编程语…

【C语言】宏详解(上卷)

前言 紧接着预处理详解&#xff08;上卷&#xff09;&#xff0c;接下来我们来讲宏&#xff08;隶属于预处理详解系列&#xff09;。 #define定义宏 #define机制包括了一个规定&#xff0c;允许把参数替换到文本中&#xff0c;这种实现通常称为宏&#xff08;macro&#xff…

AI如何创造情绪价值

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面。从智能家居到自动驾驶&#xff0c;从医疗辅助到金融服务&#xff0c;AI技术的身影无处不在。而如今&#xff0c;AI更是涉足了一个全新的领域——创造情绪价值。 AI已经能够处…

2024年【天津市安全员C证】免费试题及天津市安全员C证试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 天津市安全员C证免费试题是安全生产模拟考试一点通生成的&#xff0c;天津市安全员C证证模拟考试题库是根据天津市安全员C证最新版教材汇编出天津市安全员C证仿真模拟考试。2024年【天津市安全员C证】免费试题及天津市…

分享美好,高清无阻 - 直播极简联网解决方案

1、需求背景 随着移动互联网、UGC模式和直播平台的发展&#xff0c;网络直播的门槛日益降低&#xff0c;越来越多的人希望成为直播的主角。基于物联网的户外直播无线联网解决方案应运而生&#xff0c;满足直播者的需求。 户外直播无线联网解决方案提供了无处不在的直播体验&a…

SpringBoot与MyBatis的快速整合(基于注解)

文章目录 创建Spring Boot项目配置数据库连接信息编写MyBatis Mapper接口使用XML文件编写SQL映射配置数据源切换引入Druid依赖配置Druid数据源 配置MyBatis支持事务管理 在使用Spring Boot创建新项目或新模块时&#xff0c;如果需要使用MyBatis来进行数据库操作&#xff0c;可以…

uniapp实现微信小程序调用云函数【vue2】

在uniapp中的vue 2框架中想要改变默认的目录结构&#xff0c;将装有云函数的文件夹在运行后一起复制到unpackage 文件下&#xff0c;主要用 copy-webpack-plugin 方法来实现&#xff0c;具体步骤如下&#xff1a; 一、创建一个vue 2 框架的uniapp 二、新建一个文件夹装云函数 …

Git【版本控制命令】

02 【本地库操作】 1.git的结构 2.Git 远程库——代码托管中心 2.1 git工作流程 代码托管中心用于维护 Git 的远程库。包括在局域网环境下搭建的 GitLab 服务器&#xff0c;以及在外网环境下的 GitHub 和 Gitee (码云)。 一般工作流程如下&#xff1a; 1&#xff0e;从远程…

轻松掌握系统概况,提升工作效率

作为 Linux 系统管理员,我们经常需要了解系统的基本状况,比如当前时间、系统版本、内核信息、CPU 型号、内存使用等等。但是每次手动执行各种命令来获取这些信息,无疑是一件非常繁琐的事情。 幸运的是,我们可以通过编写一个简单的 shell 脚本来一键获取这些系统信息。让我们一…

Java 环境配置 -- Java 语言的安装、配置、编译与运行

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 002 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

【iOS】内存泄漏检查及原因分析

目录 为什么要检测内存泄漏&#xff1f;什么是内存泄漏&#xff1f;内存泄漏排查方法1. 使用Zombie Objects2. 静态分析3. 动态分析方法定位修改Leaks界面分析Call Tree的四个选项&#xff1a; 内存泄漏原因分析1. Leaked Memory&#xff1a;应用程序未引用的、不能再次使用或释…

我的编程语言学习记录:一段不断探索的旅程

目录 我的编程语言学习记录&#xff1a;一段不断探索的旅程 1.引言 2.我的编程之旅开始 第一站&#xff1a;Python — 简洁之美 第二站&#xff1a;JavaScript — 网页的魔法 第三站&#xff1a;Java — 企业级的力量 3.学习过程中的挑战与克服 1.理解概念 3.记忆语法…

牛客网刷题 | BC118 N个数之和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 输入数字N&#xf…