剑指office--栈与队列

PS:以下代码均由C++实现

1.两个栈实现队列 力扣

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

示例 1:

输入:
["CQueue","appendTail","deleteHead","deleteHead","deleteHead"]
[[],[3],[],[],[]]
输出:[null,null,3,-1,-1]

示例 2:

输入:
["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]
[[],[],[5],[2],[],[]]
输出:[null,-1,null,null,5,2]

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof

class CQueue 
{
public:
    CQueue() 
    {
        //调用栈的默认构造函数
    }
    
    void appendTail(int value) 
    {
        _pushs.push(value);//插入
    }
    
    int deleteHead()
    {
        //删除
        if(_pops.empty()&&!_pushs.empty())//如果出栈的为空且进栈的不为空,进栈的插入到出栈的站里面,然后//删除栈顶元素
        {
            while(!_pushs.empty())
           {
                _pops.push(_pushs.top());
                 _pushs.pop();
           }
           int ret= _pops.top();
           _pops.pop();
           return ret;
        }
        else if(_pops.empty()&&_pushs.empty())
            return -1;
        else//其他情况返回出栈栈顶元素
        {
            int ret= _pops.top();
           _pops.pop();
           return ret;
        }
    }
    private:
    stack<int> _pushs;//定义进栈的
    stack<int> _pops;//定义出栈的

};

2.包含main函数的栈  力扣

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

示例:

MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.min();   --> 返回 -3.
minStack.pop();
minStack.top();      --> 返回 0.
minStack.min();   --> 返回 -2.

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof

class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() 
    {
        ;
    }
    
    void push(int x) 
    {
        //插入栈的元素
        str.push(x);
        if(minstr.empty())//最小栈为空,则进栈
        {
            minstr.push(x);
        }
        else
        {
            if(x<=minstr.top())//小于等于进栈。其他情况,不进
            {
                minstr.push(x);
            }
        }
    }
    
    void pop() 
    {
        //删除
        int n=str.top();
        str.pop();
        if(n==minstr.top())
            minstr.pop();
    }
    
    int top() 
    {
        return str.top();//栈顶元素
    }
    
    int min() 
    {
        return minstr.top();//最小栈栈顶元素
    }
    private:
    stack<int> str;//栈
    stack<int> minstr;//最小栈

};

3.滑动窗口的最大值  力扣

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:

  滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/hua-dong-chuang-kou-de-zui-da-zhi-lcof

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) 
    {
        int n = nums.size();
        priority_queue<pair<int, int>> q;//优先级队列解决
        for (int i = 0; i < k; ++i) 
        {
            q.emplace(nums[i], i);//初始化元素
        }
        vector<int> ans = {q.top().first};//队列首元素
        for (int i = k; i < n; ++i) //插入,选出需要的数组
        {
            q.emplace(nums[i], i);
            while (q.top().second <= i - k) 
            {
                q.pop();
            }
            ans.push_back(q.top().first);
        }
        return ans;
    }
};

4.队列的最大值 力扣

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

示例 1:

输入:
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"]
[[],[1],[2],[],[],[]]
输出: [null,null,null,2,1,2]

示例 2:

输入:
["MaxQueue","pop_front","max_value"]
[[],[],[]]
输出: [null,-1,-1]

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/dui-lie-de-zui-da-zhi-lcof

//使用双端队列解决问题
class MaxQueue 
{
    queue<int> q;
    deque<int> d;
public:
    MaxQueue() 
    {
        
    }
    
    int max_value() 
    {
        if (d.empty())
            return -1;
        return d.front();
    }
    
    void push_back(int value) 
    {
        while (!d.empty() && d.back() < value) 
        {
            d.pop_back();
        }
        d.push_back(value);
        q.push(value);
    }
    
    int pop_front() {
        if (q.empty())
            return -1;
        int ans = q.front();
        if (ans == d.front()) 
        {
            d.pop_front();
        }
        q.pop();
        return ans;
    }
};

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

函数指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值