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

本文介绍了如何在保持入栈顺序不变的情况下,设计一个数据结构,使得在栈中实现max、push和pop操作的时间复杂度为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);
    else
        max_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;
}
运行结果

这里写图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值