leetcode_02栈

leetcode_02栈

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

C++模板编程

S.top()∶取出栈顶
S.empty:判断栈是否为空
S.push()∶将x添加至栈
S.pop()∶弹出栈顶
S.size0:栈的存储元素个数

#include<iostream>
#include<queue>
using namespace std;
int main()
{
    queue<int> Q;
    if(Q.empty())
    {
        printf("Q is empty\n");
    }
    Q.push(5);//向队列中放入元素5;
    Q.push(6);
    Q.push(10);
    printf("Q.front=%d\n",Q.front());
    Q.pop();//出队,先入的先出 5出去
    Q.pop();//先入先出,6出去
    printf("Q.front= %d\n",Q.front());
    Q.push(1);//向队列中放入1
    printf("Q.back= %d\n",Q.back());//队尾数字
    printf("Q.size=%d\n",Q.size());
    return 0;
}

例1.用队列实现栈

使用队列实现栈的下列操作:

push(x) – 元素 x 入栈
pop() – 移除栈顶元素
top() – 获取栈顶元素
empty() – 返回栈是否为空
注意:

你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。
你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-stack-using-queues
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:队列是先进先出,栈是先进后出,用一个临时队列,考虑到队列先进先出,先将需要的数字押进临时栈中,此时新元素成为头部元素,再将所有元素从临时栈搞到栈中,此时新元素最先进入队列,从而保证最先出来,实现了后进先出。

#include<iostream>
#include<queue>
using namespace std;
class MyStack{
public: MyStack(){}
void push(int x)
{
    queue<int> temp_queue;
    temp_queue.push(x);
    while(!_data.empty())
    {
        temp_queue.push(_data.front());
        _data.pop();
    }
    while(!temp_queue.empty())
    {
        _data.push(temp_queue.front());
        temp_queue.pop();
    }
}
int pop()//栈顶元素弹出动作
{
int x=_data.front();//获取栈顶元素,即为队列头部元素
_data.pop();
return x;
}
int top()
{
    return _data.front();
}
bool empty()
{
    return _data.empty();
}
private:
    queue<int> _data;
};
int main()
{
    MyStack myStack;
    myStack.push(1);
    myStack.push(2);
    myStack.push(3);
    printf("栈顶元素为: %d\n",myStack.top());

    printf("弹出元素为: %d\n",myStack.pop());
    return 0;
}

例2.用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列的支持的所有操作(push、pop、peek、empty):

实现 MyQueue 类:

void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-queue-using-stacks
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:用栈实现队列,必须使得新元素在栈底。用一个临时栈,先将所有元素导入临时栈,使得顺序倒置,然后将新元素导入临时栈,从临时栈中向栈倒数据,从而新元素在最底下。

#include<iostream>
#include<stack>
using namespace std;
class MyQueue {
public:
    /** Initialize your data structure here. */
    MyQueue() {

    }

    /** Push element x to the back of queue. */
    void push(int x) {
        std::stack<int>temp_stack;//将栈中元素临时push到栈中

        while(!_data.empty())
        {
            temp_stack.push(_data.top());
            _data.pop();
        }
        temp_stack.push(x);
        while(!temp_stack.empty())
        {
            _data.push(temp_stack.top());
            temp_stack.pop();
        }

    }

    /** Removes the element from in front of queue and returns that element. */
    int pop() {
      int x=_data.top();
      _data.pop();
      return x;
    }

    /** Get the front element. */
    int peek() {
    return _data.top();
    }

    /** Returns whether the queue is empty. */
    bool empty() {
    return _data.empty();
    }
private:std::stack<int>_data;
};

例3.最小栈

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

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:同时设置一个栈存储最小值,比较新元素,如果更小则更新压入最小值栈,不小则压入重复值,删除时同时弹出。

#include<iostream>
#include<stack>
class MinStack {
public:
    /** initialize your data structure here. */
    MinStack() {

    }

    void push(int x)
    {
        _data.push(x);
        if(_min.empty())
            _min.push(x);
        else{
            if(x>_min.top())
            {x=_min.top();}

        _min.push(x);}
    }

    void pop() {
      _data.pop();
      _min.pop();
    }

    int top() {
     return _data.top();
    }

    int getMin() {
      return _min.top();
    }
private:
    std::stack<int>_data;
    std::stack<int>_min;
};
int main()
{
    MinStack minStack;
    minStack.push(-2);
    printf("top=[%d]\n",minStack.top());
    printf("top=[%d]\n",minStack.getMin());
    minStack.push(0);
    printf("top=[%d]\n",minStack.top());
    printf("top=[%d]\n",minStack.getMin());
}

例4.合法的输出序列

给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false 。

示例 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/validate-stack-sequences
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<queue>
#include<stack>
using namespace std;
bool check_is_valid_orders(queue<int>&order)
{
    stack<int>s;//S为模拟栈
    int n=order.size();
    printf("n=%d\n",n);
    for(int i=1;i<=n;i++)
    {
        s.push(i);
        while(order.front()==s.top()&&!s.empty())
        {
            s.pop();
            order.pop();
            printf("order.front(): %d\n",order.front());
            printf("s.top(): %d \n",order.front());
        }
    }
    if(s.empty())
    {return true;}
    return false;
}
int main()
{
   queue<int>order;
   order.push(3);
    order.push(2);
    order.push(1);
    order.push(4);
    order.push(5);

    if(check_is_valid_orders(order))
    {printf("yes");}
    else
        printf("No");
    return 0;
}

二叉堆是一种特殊的堆,二叉堆是完全二元树(二叉树)或者是近似完全二元树(二叉树)。二叉堆有两种:最大堆和最小堆。最大堆:父结点的键值总是大于或等于任何一个子节点的键值;
最小堆:父结点的键值总是小于或等于任何一个子节点的键值。

#include<iostream>
#include<queue>
using namespace std;
int main()
{
    priority_queue<int, vector<int>, less<int>> big_heap;//最大堆的定义方法
    priority_queue<int, vector<int>, greater<int>> samll_Heap;//最小堆定义方法
    if(big_heap.empty())
        printf("big_heap is empty\n");
    int test[]={6,10,1,7,99,4,33};
    for(int i=0;i<7;i++)
    {
        big_heap.push(test[i]);
    }
    printf("big_heap.top=%d\n",big_heap.top());
    big_heap.push(1000);
    printf("big_heap.top=%d\n",big_heap.top());
    for(int i=0;i<3;i++)
    {
        big_heap.pop();
    }
    printf("big_heap.top=%d\n",big_heap.top());
    printf("big_heap.size()=%d\n",big_heap.size());
    return 0;
}

例1.数组中的第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

思路:比如要寻找第k大的数,则建立大小为k的一个堆,

#include<vector>
#include<queue>
#include<iostream>
using namespace std;
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k)
    {
        priority_queue<int, vector<int>, greater<int>>Q;
       for(int i=0;i<nums.size();i++)
       {
           if(Q.size()<k)
               Q.push(nums[i]);
           else if(Q.top()<nums[i])
           {
               Q.pop();
               Q.push(nums[i]);
           }
       }
       return Q.top();//返回栈顶
    }
};
int main()
{
    Solution s1;
    vector<int>nums;
    nums.push_back(1);
    nums.push_back(2);
    nums.push_back(3);
    nums.push_back(4);
    nums.push_back(5);
    int k=3;
    printf("%d\n",s1.findKthLargest(nums,k));
    return 0;
}
     {
           Q.pop();
           Q.push(nums[i]);
       }
   }
   return Q.top();//返回栈顶
}

};
int main()
{
Solution s1;
vectornums;
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
int k=3;
printf("%d\n",s1.findKthLargest(nums,k));
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值