从C语言到C++_18(stack和queue的常用函数+相关练习)力扣(中)

简介: 从C语言到C++_18(stack和queue的常用函数+相关练习)力扣

从C语言到C++_18(stack和queue的常用函数+相关练习)力扣(上):https://developer.aliyun.com/article/1521375

4. 栈和队列的相关OJ

155. 最小栈 - 力扣(LeetCode)

难度中等

设计一个支持 pushpoptop 操作,并能在常数时间内检索到最小元素的栈。

实现 MinStack 类:

  • MinStack() 初始化堆栈对象。
  • void push(int val) 将元素val推入堆栈。
  • void pop() 删除堆栈顶部的元素。
  • int top() 获取堆栈顶部的元素。
  • int getMin() 获取堆栈中的最小元素。

示例 1:

输入:

["MinStack","push","push","push","getMin","pop","top","getMin"]

[[],[-2],[0],[-3],[],[],[],[]]

输出:

[null,null,null,null,-3,null,0,-2]

解释:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin();   --> 返回 -3.

minStack.pop();

minStack.top();      --> 返回 0.

minStack.getMin();   --> 返回 -2.

提示:

  • -2^31 <= val <= 2^31 - 1
  • poptopgetMin 操作总是在 非空栈 上调用
  • push, pop, top, and getMin最多被调用 3 * 10^4
class MinStack {
public:
    MinStack() {
 
    }
    
    void push(int val) {
 
    }
    
    void pop() {
 
    }
    
    int top() {
 
    }
    
    int getMin() {
 
    }
};
 
/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

解析代码:

思路:使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。

当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,

与当前元素比较得出最小值将这个最小值插入辅助栈中;

当一个元素要出栈时,我们把辅助栈的栈顶一样元素也一并弹出;

在任意一个时刻,栈内元素的最小值就存储在辅助栈的栈顶元素中。

给个图理解理解:

class MinStack {
public:
    MinStack() { // 构造函数不用写,删掉也行
 
    }
    
    void push(int val) {
        _st.push(val);
        if(_minst.empty() || val <= _minst.top())//要先判空
        {
            _minst.push(val);//栈空或者值小于等于栈顶元素才入栈
        }
    }
    
    void pop() {
        if(_st.top() == _minst.top())
        {        //题目说栈空 不会调用pop,top和getMin,所以不判空也行
            _minst.pop();//两个栈元素相等就_minst.pop
        }
        _st.pop();//要先判断_minst要不要pop
    }
    
    int top() {
        return _st.top();
    }
    
    int getMin() {
        return _minst.top();
    }
private:
    stack<int> _st;// 一个栈完成常规接口
    stack<int> _minst; // 一个栈完成getMin
};
 
/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(val);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->getMin();
 */

拓展:如果面试的时候问到这题,面试官问你如果要插入的元素中包含大量的重复数据的话,

比如100万个1,中间包含不一样的数,要怎么优化呢?

这就考察到引用计数了。我们的辅助栈可以存一个结构体一个存值,一个计数:

可以去写写,面试时也不一定要写,可能就是讲思路,主要是考察思维或不活跃。

剑指 Offer 31. 栈的压入、弹出序列 - 力扣(LeetCode)

946. 验证栈序列 - 力扣(LeetCode)

栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)

ps(上面三题是一模一样的,血赚两题)

难度中等

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。

假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,

序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,

但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]

输出:true

解释:我们可以按以下顺序执行:

push(1), push(2), push(3), push(4), pop() -> 4,

push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

示例 2:

输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]

输出:false

解释:1 不能在 2 之前弹出。

提示:

  1. 0 <= pushed.length == popped.length <= 1000
  2. 0 <= pushed[i], popped[i] < 1000
  3. pushedpopped 的排列。
class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
 
    }
};

解析代码:

遍历两个数组,模拟入栈和出栈操作,判断两个数组是否为有效的栈操作序列。

不求同年同月同日入栈,但求同年同月同日出栈:

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        if (pushed.size() != popped.size())
        {
            return false;
        }
        stack<int> st;
        int popi = 0;//出栈序列的下标
        for (const auto& e : pushed)//遍历入栈序列
        {
            st.push(e);//不匹配就持续入,匹配就持续出
            while (!st.empty() && st.top() == popped[popi])
            {
                st.pop();//一样的话就出栈,++popi
                ++popi;
            }
        }
        //return popi == popped.size();//出栈序列全部匹配->true
        return st.empty();//st为空->true
    }
};

牛客代码:

class Solution {
public:
    bool IsPopOrder(vector<int> pushV,vector<int> popV) {
        if (pushV.size() != popV.size())
    {
      return false;
    }
        stack<int> st;
        int popi = 0;
        for(const auto& e : pushV)
        {
            st.push(e);
            while(!st.empty() && st.top() == popV[popi])
            {
                st.pop();
                ++popi;
            }
        }
        return st.empty();
    }
};

从C语言到C++_18(stack和queue的常用函数+相关练习)力扣(下):https://developer.aliyun.com/article/1521384


目录
相关文章
|
3天前
|
C++ 容器
C++之评委打分案例(vector与deque容器练习)
C++之评委打分案例(vector与deque容器练习)
8 1
|
5天前
|
C语言
C语言练习代码第一篇
C语言练习代码第一篇
|
10天前
|
C++ 容器
【C++】拷贝构造函数、拷贝赋值函数与析构函数
【C++】拷贝构造函数、拷贝赋值函数与析构函数
61 6
|
6天前
|
编译器 程序员 语音技术
C++的超20种函数类型分享
C++超20种函数类型:编程语言规定规则,编译器实现预定规则
|
6天前
|
C++
C++函数的返回数据写法的思路
C++函数使用尾置返回类型、decltype、类型别名返回一个数组引用
|
7天前
|
关系型数据库 MySQL 测试技术
技术分享:深入C++时间操作函数的应用与实践
技术分享:深入C++时间操作函数的应用与实践
11 1
|
10天前
|
安全 C++ 开发者
C++一分钟之-函数参数传递:值传递与引用传递
【6月更文挑战第19天】C++中函数参数传递涉及值传递和引用传递。值传递传递实参副本,安全但可能效率低,适合不变对象;引用传递传递实参引用,允许修改,用于高效修改或返回多值。值传递示例显示交换不生效,而引用传递示例实现交换。常量引用则防止意外修改。选择传递方式需考虑效率与安全性。
25 2
|
15天前
|
C++
C++小练习:猜数游戏
C++小练习:猜数游戏
|
1天前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
1天前
|
程序员 编译器 C++
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
7 0