编程题——关于栈和队列

1 篇文章 0 订阅
1 篇文章 0 订阅

 

目录

实现栈的求最小值函数(剑指欧肥儿)

栈的压入,弹出序列(剑指欧肥儿)

用两个栈实现队列(剑指欧肥儿)

滑动窗口的最大值(剑指欧肥儿)


 

  •  实现栈的求最小值函数(剑指欧肥儿)

class Solution {
public:
    void push(int value) {
        StackInt.push(value);
        if(StackMin.empty())
            StackMin.push(value);
        else if(StackMin.top()<value)
            StackMin.push(StackMin.top());
        else
            StackMin.push(value);
    }
    void pop() {
        if(!StackInt.empty())
        {
            StackInt.pop();
            StackMin.pop();
        }
    }
    int top() {
        return StackInt.top();
    }
    int min() {
        return StackMin.top();
    }
private:
    stack<int> StackInt;
    stack<int> StackMin;
};

代码思路:

  1. 声明两个栈,一个是放所有值的栈(StackIn),一个是顶部放最小值的栈(StackMin)
  2. 压入时,两个栈都要压入数,StackIN压入value;而StackMin需要和它栈中top位置的值比较,如果value小于等于StackMin.top()压入value,如果value大于StackMin.top()则压入StackMin.top()
  3. 弹出时,两个栈都弹出顶端的数,这样保证了两个栈的同步性,保证StackMin的顶部是当前StackIn整个栈的最小值。
  4. 返回StackIn的顶端的值。
  5. 返回StackIn里的最小值,即StackMin里的顶端值。

  • 栈的压入,弹出序列(剑指欧肥儿)

题目描述:

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

解题答案:

class Solution{
public:
    bool IsPopOrder(vector<int> pushV, vector<int> popV){
    
        if(pushV.size() != popV.size() || popV.size() == 0 || pushV.size() == 0){
            return false;
        }    

        stack <int> st //加入一个辅助栈
        int id = 0;
        for(int i = 0; i < popV.size(); i++){
            while(st.empty() || st.top() != popV[i]){
                if(id >= st.top ) 
                {//以防越界       
                    return false;
                }
                st.push(pushV[id++]);
            }
            st.pop();
        }

        if(st.empty()){
            return true;
        }else{
            return false;
        }
    
    }

}

代码思路:

  1. 边界值判断,去除不符合条件的输入向量
  2. 依次遍历输出栈(popV)的每一个数,再循环判断popV对应的数是否等于st(辅助栈)顶端的数,如果不等于则继续压入pushV的数,如果等于则st弹出这个数。注意循环的时候有可能一直没找到符合条件的数,就会变成死循环,故判断是否变量下标越界,越界直接false(因为这意味着弹出序列包含了压入序列里没有的数)。
  3. 最后判断辅助栈st是否为空,为空则弹出序列正确,否则不正确。

向量vector的大小:vector.size()

取向量vector里的数:vector[i]  //取数类似于数组

这道题的思维:

借用一个辅助的栈,遍历压栈顺序,先讲第一个放入栈中,这里是1,然后判断栈顶元素是不是出栈顺序的第一个元素,这里是4,很显然1≠4,所以我们继续压栈,直到相等以后开始出栈,出栈一个元素,则将出栈顺序向后移动一位,直到不相等,这样循环等压栈顺序遍历完成,如果辅助栈还不为空,说明弹出序列不是该栈的弹出顺序。

举例:

入栈1,2,3,4,5

出栈4,5,3,2,1

首先1入辅助栈,此时栈顶1≠4,继续入栈2

此时栈顶2≠4,继续入栈3

此时栈顶3≠4,继续入栈4

此时栈顶4=4,出栈4,弹出序列向后一位,此时为5,,辅助栈里面是1,2,3

此时栈顶3≠5,继续入栈5

此时栈顶5=5,出栈5,弹出序列向后一位,此时为3,,辅助栈里面是1,2,3


  • 用两个栈实现队列(剑指欧肥儿)

题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

代码:

class Solution{
public:
    void push(int node){
        stack1.push(node);

    }

    int pop(){
        if(stack2.empty()){
            while(!stack1.empty()){
                stack2.push(stack1.top());
                stack1.pop();
           } 
        }
        int a = stack2.top();
        stack2.pop();
        return a;

    }

private:
    stack<int> stack1;
    stack<int> stack2;

}

代码思路:

  1. 压栈就压stack1.
  2. 弹出时,首先检测stack2是不是空的,如果是空的,就把stack1里从顶到底压入stack1,再弹出stack2顶部数据;如果stack2不是空的,则直接把stack2的顶部数据弹出。
  3. 这样做的好处,不会每一次压栈都要重新生成一次stack2(因为生成stack2时间为把stack1全部n个节点压入,时间为n),只有在stack2全部用完了,才会重新生成stack2。节约时间,而且省空间。

代码核心:

if(stack2.empty()){
    while(!stack1.empty()){
    stack2.push(stack1.top());
    stack1.pop();
    } 
}

  • 滑动窗口的最大值(剑指欧肥儿)

题目描述:

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}

解题代码:

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        vector<int> max;
        
        if(num.size() < size || size < 1) return max;
        
        int m;
        for(int i = 0; i < num.size() - size + 1; i++){ //根据max中有多少个元素来遍历
            m = num[i];
            for(int j = i + 1; j < i + size; j++){
                if( m < num [j]){
                    m = num[j];
                }
            }
            max.push_back(m);
        }
        
        return max;
    }
};

这道题的思维:

  1. 不要引入栈!这道题和栈没关系!
  2. 切入点很重要,切入点正确了,这道题就很简单了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值