牛客网 栈和队列 C++实现 题目汇总

1:设计一个有getMin功能的栈

class MinStack {
public:
    //stackData.top()只会大于或等于stackMin.top()的值
    stack<int>stackData;
    stack<int>stackMin;
    MinStack() {}

    void push(int x) {
        stackData.push(x);//栈空或者x<=stackMin.top()
        if(stackMin.size() == 0 || x <= stackMin.top())
            stackMin.push(x);

    }
    void pop() {
        //出栈时需要同步
        int val=stackData.top();
        stackData.pop();
        if(val==stackMin.top())
            stackMin.pop();
    }

    int top() {
      if(!stackData.empty())
          return stackData.top();
      else
          return -1;
    }

    int min() {
        return stackMin.empty()?-1:stackMin.top();
    }
};

 

2:由两个栈组成的队列

class CQueue {
public:
    //A用来入栈,B用来出栈
    // 出栈时B中若有元素则依次弹出,否则就将A中全部转移到B中再弹出
    stack<int>A;
    stack<int>B;
    CQueue() {}

    void appendTail(int value) {
        A.push(value);
    }

    int deleteHead() {
        if(B.empty()){
            while (!A.empty()){
                B.push(A.top());
                A.pop();
            }
        }
        if(B.empty())
            return -1;//两栈空空
        else{
            int val=B.top();
            B.pop();
            return val;
        }
    }
};

 

3:如何仅用递归函数和栈操作逆序一个栈?

class Solution{
public:
    int getAndRemoveLastElement(stack<int>&stack){
        int result=stack.top();
        stack.pop();
        if(stack.empty())
            return result;
        else{
            int last=getAndRemoveLastElement(stack);
            stack.push(result);
            return last;
        }
    }
};

 

4:用一个栈实现另一个栈的排序问题

class Solution{
public:
    void sortStackByStack(stack<int>&S){
        stack<int>help;//辅助栈,元素从顶往下升序排列
        while (!S.empty()){
            int cur=S.top();
            S.pop();
            //每次加入help中的元素为当前最小值
            while (!help.empty() && help.top() < cur){
                S.push(help.top());
                help.pop();
            }
            help.push(cur);
        }
        //挪回S中
        while (!help.empty()){
            S.push(help.top());
            help.pop();
        }
    }
};

 

5:用栈来求解汉诺塔问题

class Solution{
public:
    //函数调用Solution.hanoi(N,A,B,C);将N个盘子从A移动到C
    void hanoi(int N ,char source , char relay ,char destination){
        if(N == 1)
            cout << source << "-->" << destination << endl ;
        else
        {
            //N>=2时,将(N-1)个从A移动到B,借助C;再将N-1从B移动到C,借助A
            hanoi(N-1 , source , destination , relay) ;
            cout << source << "-->" << destination << endl ;
            hanoi(N-1 , relay , source , destination) ;
        }
    }
};

 

6:生成窗口最大值问题

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;    //用来存结果的vector
        deque<int> temp;   //双端队列

        for(int i=0; i<nums.size(); ++i){
            while(!temp.empty() && nums[i] > nums[temp.back()]){
                //while这步操作是为了让当前窗口最大值的索引值放到temp的队头
                temp.pop_back();
            }
            //这里的if判断条件中的第二个是为了判断队头是否过期,也就是说队头的索引是否小于当前索引 
            if(!temp.empty() && temp.front() < i - k + 1) temp.pop_front();
                temp.push_back(i);
                
            if(i>=k-1)  res.push_back(nums[temp.front()]);
        }
        return res;
    }
};

 

7:最大值减去最小值小于或等于num的子数组数量

链接:https://www.nowcoder.com/questionTerminal/5fe02eb175974e18b9a546812a17428e
来源:牛客网

int getNum(vector<int>& arr, int num)
{
    int n = arr.size();
    deque<int> qmin, qmax;
    int i=0, j=0, res=0; 
    while(i<n) {
        while(j<n) {
            while(!qmin.empty() && arr[qmin.back()]>=arr[j]) {
                qmin.pop_back();
            }
            qmin.push_back(j);
             
            while(!qmax.empty() && arr[qmax.back()]<=arr[j])
            {
                qmax.pop_back();
            }
            qmax.push_back(j);
             
            if(arr[qmax.front()] - arr[qmin.front()] > num) break;
            j++;
        }
        if(qmin.front()==i) qmin.pop_front();
        if(qmax.front()==i) qmax.pop_front();
        res += j - i;
        i++;
    }
    return res;
}

8:求最大子矩阵的大小

 

class Solution 
{
public:
    int maximalRectangle(vector<vector<int>>& matrix) 
    {
        if(matrix.empty())
        {
            return 0;
        }
        int maxArea = 0;
        vector<int> height(matrix[0].size(), 0);
        for(int i=0; i<matrix.size(); ++i)
        {
            for(int j=0; j<matrix[0].size(); ++j)
            {
                height[j] = (matrix[i][j] == 0) ? 0 : height[j] + 1;
            }
            maxArea = (maxRecFromBottom(height) > maxArea) ? maxRecFromBottom(height) : maxArea;
        }
        return maxArea;
    }
    
    int maxRecFromBottom(vector<int> height)
    {
        if(height.size() == 0)
        {
            return 0;
        }
        int maxArea = 0;
        stack<int> stack1;
        for(int i=0; i<height.size(); ++i)
        {
            while(!stack1.empty() && height[i] <= height[stack1.top()])
            {
                int j = stack1.top();
                stack1.pop();
                int k = stack1.empty() ? -1 : stack1.top();
                int curArea = (i - k - 1) * height[j];
                maxArea = (maxArea > curArea) ? maxArea : curArea;
            }
            stack1.push(i);
        }
        while(!stack1.empty())
        {
            int j = stack1.top();
            stack1.pop();
            int k = stack1.empty() ? -1 : stack1.top();
            int curArea = (height.size() - k - 1) * height[j];
            maxArea = (maxArea > curArea) ? maxArea : curArea;
        }
        return maxArea;
    }
};

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值