[WPS笔试题]实现栈的push,pop,max且时间复杂度为O(1)

今天做了一下WPS的笔试题,遇到了一道关于栈的题,觉得挺有意思的,就写篇博客分享一下吧~~

题目要求:要求实现栈的数据结构,在该类型中实现一个能够得到栈的最大元素的max函数,在该栈中,调用max,push,pop的时间复杂度是O(1).

解题思路:我们首先会想到的大概是,找最大元素不就排个序,直接取栈顶的元素不就好了吗。可是这时,我们就把这个入栈的顺序修改了。这并不是我们想要的。在不改变入栈顺序的情况下,我们只能用一个辅助栈来解决这一类问题。

此时,我们可以将最大的元素放到这个辅助栈中,取辅助栈的栈顶元素就ok了。问题来了?

如何给辅助栈中放最大元素???

这里分为以下几种情况:

  1. 我们先往数据栈中放元素,当辅助栈为空时,直接将数据栈中的元素放入辅助栈中
  2. 当辅助栈中有数据时,我们需要比较将要入栈的数据是否大于当前辅助栈中的数据,如果大于则继续往辅助栈中放数据,否则放入当前辅助栈中的数据(这里用的比较巧妙,是为了寻找次大的数据,当pop出数据后,仍然可以找到次大的数据

最终解题思路

这里写图片描述

代码实现

由于自己考虑到了string类的特殊情况,里边还使用了仿函数的形式,实现了简单的模板类。
#include<iostream>
using namespace std;
#include<stack>
#include<assert.h>
#include<string>template<class T>
struct Less
{bool operator()(const T& left,const T& right){return left < right;}
};template<class T>
struct Greater
{bool operator()(const T& left,const T& right){return left >= right;}
};template<class T,class Compare>
class StackWithMax
{
public:void Push(const T& data);void Pop();T& MaxValue();private:stack<T> value_st;stack<T> max_st;
};template<class T,class Compare>
void StackWithMax<T,Compare>::Push(const T& data)
{value_st.push(data);if(max_st.size() == 0 || Compare()(data,max_st.top()))max_st.push(data);elsemax_st.push(max_st.top());
}template<class T,class Compare>
void StackWithMax<T,Compare>::Pop()
{assert(value_st.size() >= 0 && max_st.size() >= 0);max_st.pop();value_st.pop();
}
template<class T,class Compare>
T& StackWithMax<T,Compare>::MaxValue()
{assert(value_st.size() >= 0 && max_st.size() >= 0);return max_st.top();
}

测试代码

int main()
{StackWithMax<int,Greater<int>> st;st.Push(3);st.Push(4);st.Push(2);st.Push(1);st.Push(4);cout<<st.MaxValue()<<endl;st.Pop();cout<<st.MaxValue()<<endl;StackWithMax<string,Greater<string>> st1;st1.Push("aaa");st1.Push("bbb");st1.Push("ccc");st1.Push("fff");st1.Push("eee");cout<<st1.MaxValue()<<endl;st1.Pop();cout<<st1.MaxValue()<<endl;return 0;
}

运行结果

这里写图片描述

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

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

相关文章

[剑指Offer]替换空格

今天看题的时候&#xff0c;遇到一个替换空格的题目&#xff0c;分析一下哈。 题目要求&#xff1a;把字符串中的每个空格替换成“%20”。例如输入“we are happy”&#xff0c;则输出“we%20are%20happy”。 解题思路&#xff1a;我们首先想到的是&#xff1a;移位思想。遇到…

C语言关键字 ISO/ANSI C90 C99 C11

面试考点 https://blog.csdn.net/csdn_kou/article/details/81113215 * 有的常用的我们都不知道是关键字&#xff0c;比如sizeof.这是面试中的考点&#xff0c;要注意。 * 同时当回答C语言中有多少关键字时&#xff0c;要回答前题条件&#xff0c;时针对哪一个版本

关于sudo

之前&#xff0c;我们使用sudo的时候&#xff0c;是因为其用户本身具有root权限&#xff0c;所以可以sudo后执行相关操作&#xff0c;但是对于普通用户来说&#xff0c;它是既不具有sudo权限&#xff0c;又不在sudo用户组中&#xff0c;那么我们来研究一下如何将新创建的用户添…

Bash入门

Bash简介&#xff1a; Bash&#xff08;GNU Bourne-Again Shell&#xff09;是一个为GNU计划编写的Unix shell&#xff0c;它是许多Linux平台默认使用的shell。 shell是一个命令解释器&#xff0c;是介于操作系统内核与用户之间的一个绝缘层。准确地说&#xff0c;它也是能力…

线程之售票系统pthread_mutex,_lock,_unlock

先看一下这篇文章 https://blog.csdn.net/csdn_kou/article/details/81148268 四个人同时买票票&#xff0c;引出线程 #include "head.h" int ticket 100; void * route(void *arg) {char *id (char *)arg;while(1){if(ticket>0){usleep(1000);printf("…

Bash基本语法

1. 变量赋值 a375 hello$a 这里需要注意的是&#xff0c;等号两边不能有空格 还有一个例子是这样的 例1&#xff1a; 结果为&#xff1a; 关于上述&#xff0c;主要有如下几点&#xff1a; $hello和${hello}是一样的&#xff0c;在bash中如果遇到空格&#xff0c;tab键时&a…

关于fd和fp(fd:file descirptor fp:file pointor)

通常&#xff0c;我们在输入数据或输出数据的设备为键盘或者显示器。当然&#xff0c;我们比较熟悉的输入输出&#xff0c;可能就是对于文件的操作&#xff0c;还有直接从终端输出&#xff0c;显示到显示器上。在C语言中&#xff0c;我们使用fopen,fclose,fread,fwrite对文件进…

[linux]wait详解

wait&#xff1a;进程等待 主要有两种等待方式&#xff1a;阻塞式等待和非阻塞式等待 阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;父进程将会一直等待着子进程运行结束&#xff0c;并且自己什么事都不干 非阻塞式等待&#xff1a;如果子进程正在运行&#xff0c;…

[Linux]消息队列

我们知道进程间通信的方法有多种&#xff0c;主要有管道&#xff0c;消息队列&#xff0c;信号量&#xff0c;共享内存&#xff0c;socket等。之前介绍过管道&#xff0c;今天再介绍一个新的概念–消息队列。 消息队列&#xff1a;将一个进程到另一个进程之间发送数据块的方式…

C++关键字速查手册

[TOC] https://blog.csdn.net/csdn_kou/article/details/81113215 C98关键字 C11 关键字共73个 alignas alignof用于获取取指定表达式指定的&#xff08;类似sizeof&#xff0c;可以直接是类型名&#xff09;的对齐(alignment)。alignas用于声明时指定对齐类似于现有的类型…

[Linux]信号

Linux下的信号是一个什么概念呢。我们在现实生活中也遇到过信号之类的。比如红绿信号灯&#xff0c;班主任叫你去办公室并且脸色不好&#xff0c;诸如此类的都会给你一个信号。让你辨别事情的发生。同样&#xff0c;Linux下也有许多的信号&#xff0c;让你执行相应的操作。比如…

[数据结构]Map和Set

说起map和set&#xff0c;想必我们都学过红黑树了吧&#xff0c;map和set就是红黑树的一个应用领域。它的底层就是由红黑树来实现的。下面简单说一下map和set的使用吧。 首先&#xff0c;有一个栗子是这样的&#xff0c;让我们统计出每种水果出现的次数。 我们会想到怎么解决…

linux之信号

信号&#xff1a;在生活中&#xff0c;我们遇到过不同种类的信号&#xff0c;比如&#xff1a;&#xff08;交通信号&#xff0c;乃至某个人的表情&#xff0c;动作等带给你不同的信号&#xff09;然而&#xff0c;在我们的linux下&#xff0c;我们最熟悉的就是&#xff0c;当遇…

[Linux]继续探究mysleep函数(竞态条件)

之前我们探究过mysleep的简单用法&#xff0c;我们实现的代码是这样的&#xff1a; #include<stdio.h> #include<signal.h>void myhandler(int sig) {}unsigned int mysleep(unsigned int timeout) {struct sigaction act,oact;act.sa_handler myhandler;sigempt…

[Linux]死锁

死锁是指多个进程在运行过程中因争夺资源而造成的一种僵局&#xff0c;当进程处于这种僵持状态时&#xff0c;若无外力作用&#xff0c;它们都将无法再向前推进。之前信号量的时候我们知道&#xff0c;如果多个进程等待&#xff0c;主要体现在占有锁的问题上。死锁也可以被定义…

[Linux]线程安全和可重入函数

线程安全&#xff1a;一个函数被称为线程安全的&#xff0c;当且仅当被多个并发进程反复调用时&#xff0c;它会一直产生正确的结果。如果一个函数不是线程安全的&#xff0c;我们就说它是线程不安全的。 重入&#xff1a;函数被不同的控制流程调用,有可能在第一次调用还没返回…

[Linux]信号量

信号量是一个计数器&#xff0c;用于为多个进程提供对共享数据对象的访问。 在信号量上只有三种操作可以进行&#xff0c;初始化、递增和增加&#xff0c;这三种操作都是原子操作。递减操作可以用于阻塞一个进程&#xff0c;增加操作用于解除阻塞一个进程。 为了获得共享资源…

[Linux]关于SIGCHLD

之前我们就学过&#xff0c;关于wait和waitpid来处理僵尸进程&#xff0c;父进程等待子进程结束后自己才退出&#xff0c;这样的方法有俩种方式&#xff0c;一种是父进程死死的等子进程退出&#xff0c;也就是使用阻塞的方式等待子进程退出&#xff0c;另一种方式是通过非阻塞的…

C语言思维导图

本人能力有限&#xff0c;知识点难免概括不全&#xff0c;如有错误欢迎指正