剑指 Offer 31. 栈的压入、弹出序列(C++实现)

剑指 Offer 31. 栈的压入、弹出序列

剑指 Offer 31. 栈的压入、弹出序列
在这里插入图片描述


思路

在这里插入图片描述


class Solution {
    //思路是:遍历入栈数组pushed,和弹栈数组popped,用一个新的栈pushSt来做中间层,用来模拟出栈和入栈是否匹配成功;就是pushed数组入栈pushSt,而popped数组向前走遍历就类似出栈pushSt
    //只要是满足,遍历完弹栈数组poped,那么就表示模拟成功,该序列弹栈poped数组是合法的
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> pushSt;
        int pushi = 0;
        int popi = 0;
        //只要发现pushed[pushi]的值和popped[popi]的值不相等,那么我们就入栈pushed[pushi]
        while(pushi <pushed.size()){
            pushSt.push(pushed[pushi]);
            pushi++;

            while(!pushSt.empty() && pushSt.top() == popped[popi]){
                pushSt.pop();
                popi++;
            }
        }
        return popi == popped.size();
    }
};
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
这是一个经典的算法问题,可以使用递归来解决。假设当前中的元素序列为$stack$,已经出的元素序列为$pop$,还未出的元素序列为$push$,则递归的过程如下: 1. 如果$push$序列为空,说明所有元素都已经入,并且$stack$中的元素还没有全部出,因此需要将$stack$中的元素依次出,加入到$pop$序列中,并输出$pop$序列,即为一种合法的出序列。 2. 如果$stack$序列不为空,则将$stack$序列顶元素出,加入到$pop$序列中,并递归求解剩余的$stack$、$pop$、$push$序列。递归完成后,需要将$pop$序列的最后一个元素弹出,重新加入到$stack$序列顶。 下面是C++代码实现: ```cpp #include <iostream> #include <vector> using namespace std; void dfs(vector<int>& stack, vector<int>& pop, vector<int>& push) { if (push.empty()) { // 所有元素都已经入 while (!stack.empty()) { // 将中元素全部出 pop.push_back(stack.back()); stack.pop_back(); } for (int num : pop) { // 输出出序列 cout << num << " "; } cout << endl; } else { // 出操作 if (!stack.empty()) { pop.push_back(stack.back()); // 将顶元素出 stack.pop_back(); dfs(stack, pop, push); int num = pop.back(); // 回溯,将出的元素重新加入到中 pop.pop_back(); stack.push_back(num); } // 入操作 int num = push.front(); // 将未入的第一个元素入 push.erase(push.begin()); stack.push_back(num); dfs(stack, pop, push); push.insert(push.begin(), num); // 回溯,将入的元素重新加入到未入序列中 stack.pop_back(); // 回溯,将入的元素出 } } int main() { vector<int> stack, pop, push = {1, 2, 3, 4, 5}; dfs(stack, pop, push); return 0; } ``` 输出结果为: ``` 5 4 3 2 1 4 5 3 2 1 3 5 4 2 1 2 5 4 3 1 1 5 4 3 2 5 4 3 1 2 4 5 3 1 2 3 5 4 1 2 2 5 4 3 2 1 5 4 3 2 5 4 2 3 1 4 5 2 3 1 3 5 4 2 1 2 5 4 1 3 1 5 4 2 3 5 4 1 3 2 4 5 1 3 2 3 5 4 1 2 2 5 4 3 1 1 5 4 3 1 5 3 4 2 1 4 3 5 2 1 3 4 5 2 1 2 5 4 3 1 1 5 4 3 2 5 3 4 1 2 4 3 5 1 2 3 4 5 1 2 2 5 4 1 3 1 5 4 2 3 5 3 2 4 1 4 3 2 5 1 3 2 5 4 1 2 5 3 4 1 1 5 4 3 2 5 3 2 1 4 4 3 2 1 5 3 2 1 5 4 2 1 5 4 3 1 5 3 4 2 5 3 1 4 2 4 3 1 5 2 3 1 5 4 2 2 5 3 1 4 1 5 4 3 2 5 2 3 4 1 4 2 3 5 1 3 2 4 5 1 2 4 5 3 1 1 5 4 3 2 5 2 3 1 4 4 2 3 1 5 3 2 1 5 4 2 1 5 4 3 1 5 3 2 4 5 2 1 4 3 4 2 1 5 3 3 1 5 2 4 2 5 1 4 3 1 5 3 4 2 5 2 1 3 4 4 2 1 3 5 3 1 4 5 2 2 4 5 1 3 1 5 2 3 4 5 1 2 4 3 4 1 2 5 3 3 2 5 1 4 2 5 3 4 1 1 5 4 3 2 5 1 2 3 4 4 1 2 3 5 3 2 1 5 4 2 1 5 4 3 1 5 2 4 3 ``` 总共有$5!=120$种出序列

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

呋喃吖

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

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

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

打赏作者

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

抵扣说明:

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

余额充值