链接


牛客OJ:栈的压入、弹出序列

九度OJ:http://ac.jobdu.com/problem.php?pid=1366

GitHub代码: 022-栈的压入弹出序列

CSDN题解:剑指Offer–022栈的压入、弹出序列

牛客OJ 九度OJ CSDN题解 GitHub代码
栈的压入、弹出序列 1366-栈的压入、弹出序列 剑指Offer–022栈的压入、弹出序列 022-栈的压入弹出序列

您也可以选择回到目录-剑指Offer–题集目录索引

题意


题目描述

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

假设压入栈的所有数字均不相等。

例如序列1,2,3,4,5是某栈的压入顺序,

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

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

分析


辅助栈模拟入栈出栈过程


思路:

开辟一个辅助栈,模拟入栈出战过程(假设pa为入栈序列,pb为出战序列)

pa中的元素依次压入辅助栈

新压入的元素与弹出序列的栈底相同,辅助栈弹出,同时pb向上移动

不相同了pa中的元素继续入辅助

  • 如果下一个弹出的数字刚好是栈顶数字,则直接弹出。

  • 若下一个弹出的数字不在栈顶,则把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止。

  • 若所有的数字都压入栈了仍没有找到下一个弹出的数字,则表明该序列不可能滴一个弹出序列。

#include <iostream>
#include <stack>
#include <vector>using namespace std;//  调试开关
#define __tmain main#ifdef __tmain#define debug cout#else#define debug 0 && cout#endif // __tmainclass Solution
{
public:bool IsPopOrder(vector<int> pushV,vector<int> popV){if(pushV.size( ) == 0 || popV.size( ) == 0){return false;}stack<int> s;int push, pop;s.push(pushV[0]);debug <<"push" <<pushV[0] <<endl;for(push = 0, pop = 0;push < pushV.size() && pop < popV.size( );){if(s.empty( ) != true && s.top( ) == popV[pop])        //  当前栈顶元素正好是出栈序列中的元素{debug <<"pop"<<popV[pop] <<endl;// 模拟出栈的过程s.pop( );pop++;}else{//  模拟入栈的过程s.push(pushV[++push]);debug <<"push" <<pushV[push] <<endl;}}if(s.empty( ) == true){return true;}else{return false;}}
};int __tmain( )
{int nPush[5] = {1,2,3,4,5};int nPop1[5] = {4,5,3,2,1};int nPop2[5] = {4,3,5,1,2};int nPop3[5] = {5,4,3,2,1};int nPop4[5] = {4,5,2,3,1};Solution solu;cout <<solu.IsPopOrder(vector<int>(nPush, nPush + 5), vector<int>(nPop1, nPop1 + 5)) << endl;cout <<solu.IsPopOrder(vector<int>(nPush, nPush + 5), vector<int>(nPop2, nPop2 + 5)) << endl;cout <<solu.IsPopOrder(vector<int>(nPush, nPush + 5), vector<int>(nPop3, nPop3 + 5)) << endl;cout <<solu.IsPopOrder(vector<int>(nPush, nPush + 5), vector<int>(nPop4, nPop4 + 5)) << endl;return 0;
}

我们这里用了一个辅助栈来模拟出栈入栈的过程,思路很简单很清晰,但是又没有可以优化的地方么

用PushV入栈序列作为辅助栈


其实由于当前栈的动作是肯定超不出pushV序列的,因此我们可以直接用PushV入栈序列作为我们的模拟栈,而用top去维护入栈出栈的操作

这种方法时间复杂度 O(n) O(n),空间复杂度 O(1) O(1),但是要修改输入参数PushV的值


class Solution
{
public:bool IsPopOrder(vector<int> pushV,vector<int> popV){if(pushV.size( ) == 0 || popV.size( ) == 0){return false;}int top = -1, push = 0, pop = 0;++top;debug <<"push" <<pushV[top] <<endl;while(push < pushV.size() && pop < popV.size( )){if(top != -1 && pushV[top] == popV[pop])        //  当前栈顶元素正好是出栈序列中的元素{debug <<"pop"<<popV[pop] <<endl;// 模拟出栈的过程top--;pop++;}else{//  模拟入栈的过程pushV[++top] = pushV[++push];debug <<"push" <<pushV[push] <<endl;}}debug <<top <<push <<pop <<endl;return (top == -1);}
};

或者直接使用

class Solution
{
public:bool IsPopOrder(vector<int> pushV,vector<int> popV){if(pushV.empty( ) || popV.empty( ) || pushV.size( )!= popV.size( )){return false;}for(int i = 0;i < pushV.size();){if(pushV[i] == popV[0]){pushV.erase(pushV.begin( ) + i);popV.erase(popV.begin( ));i--;                                // 模拟出栈}else{i++;                                //  模拟入栈}}return pushV.empty( );}};

发现规律


这个是看到的别人的做法

不一样的思路:

  1. 我先取出pop序列的第一个(比如pop【3,2,4,5,1】),在push序列中找到这个位置,push【1,2,3,4,5】,

  2. 此时我们找到了3的位置.那么下一个pop的数字(此时的数字是2)必然是,push中3的前一个数字,或者后面的数字。否则返回False
    如此循环直到最后,判断长度相等,就是弹出序列。否则返回False.

# -*- coding:utf-8-*-class Solution:def IsPopOrder(self, pushV, popV):# write code hereif len(pushV) != len(popV):return Falseelif len(pushV) ==0:return Falsex = popV[0]if x not in pushV:return Falsefor i in range(len(popV)) :position = pushV.index(popV[i])if len(pushV) == 1 :if pushV[0] == popV[i]:return Truetry:if popV[i+1] == pushV[position-1]:pushV.remove(pushV[position])elif popV[i+1] in pushV[position:]:pushV.remove(pushV[position])else:return Falseexcept IndexError:return Falseelse:return Trueif __name__ == "__main__" :nPush = [ 1, 2, 3, 4, 5 ]nPop1 = [ 4, 5, 3, 2, 1 ]nPop2 = [ 4, 3, 5, 1, 2 ]nPop3 = [ 5, 4, 3, 2, 1 ]nPop4 = [ 4, 5, 2, 3, 1 ]solu = Solution( )print solu.IsPopOrder(nPush, nPop1)print solu.IsPopOrder(nPush, nPop2)print solu.IsPopOrder(nPush, nPop3)print solu.IsPopOrder(nPush, nPop4)

参考


栈的压入、弹出序列

面试题20:栈的压入、弹出序列

牛客网讨论区-[编程题]栈的压入、弹出序列

栈的压入与弹出序列

剑指Offer--022-栈的压入、弹出序列相关推荐

  1. 【LeetCode】剑指 Offer 31. 栈的压入、弹出序列

    [LeetCode]剑指 Offer 31. 栈的压入.弹出序列 文章目录 [LeetCode]剑指 Offer 31. 栈的压入.弹出序列 package offer;import java.uti ...

  2. 【剑指offer-Java版】22栈的压入弹出序列

    栈的压入弹出序列:给定两个序列,一个是压入顺序,判断另外一个是否是该压入顺序的一个弹出顺序 思路:纯粹的模拟栈的压入和弹出顺序 分别遍历压栈序列seq1和另一个序列seq2 比较当前栈顶元素和seq2 ...

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

    题目描述 输入两个整数序列,第一个序列表示栈的压入书序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相同.例如1.2.3.4.5是某栈的压入序列,序列5.4.3.2.1是该栈对应的一 ...

  4. 剑指offer:栈的压入、弹出序列

    题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...

  5. 剑指OFFER之栈的压入、弹出序列(九度OJ1366)

    题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...

  6. 《剑指offer》-- 栈的压入与弹出序列、把字符串转化为整数、扑克牌顺子、孩子们的游戏(圆圈中最后剩下的数)

    一.栈的压入与弹出序列: 1.题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序. 假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序 ...

  7. 剑指offer(21):栈的压入、弹出序列

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

  8. 《剑指offer》栈的压入、弹出序列

    题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对 ...

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

    栈的压入.弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2 ...

  10. java输出栈的弹出序列_剑指offer:栈的压入、弹出序列(Java)

    1.题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 ...

最新文章

  1. 硬盘盘符双击无法打开,只能右键打开(解决方法)(转载)
  2. tc写入txt成功却没有内容_挖洞经验 | 构造UserAgent请求头内容实现LFI到RCE提权
  3. ALV添加文字输入框
  4. 第三章 用户界面设计
  5. python用于数据分析的案例_Python数据分析经典案例
  6. 北漂周记--第2记--培训开始
  7. python list方法操作_Python 列表(List)操作方法详解
  8. mysql 5.7 数据库备份_mysql 5.7 数据库备份
  9. 计算机网络cr什么意思,网络用语cr是什么意思
  10. LoadRunner 12 发布,主推云
  11. win7计算机锁频图片怎么设置,Win7系统怎么使用注册表设置锁屏壁纸的图文教程...
  12. 央视就《新闻联播》“火炬手空手捐款”致歉
  13. Android在线购物商城 app端+后台
  14. 7-1 房屋分拆 (25 分)(C语言版)
  15. 从零开始写CMOS摄像头驱动(一)
  16. 为您员工远程工作执行BYOD策略保驾护航
  17. 模拟通讯录系统2.0
  18. DophinScheduler server部分 核心代码详细解析——掌控任务和进程的呼吸与脉搏:log、monitor与registry
  19. 【SDCC 2016】蘑菇街、华为、阿里巴巴、58到家、同程旅游、链家网、京东的架构变迁与技术演进...
  20. Android12.0 默认开启WLAN热点设置默认热点名称和密码

热门文章

  1. 三个警察和三个囚徒的过河问题
  2. 关于需求响应式公共交通的那些事(下)
  3. URL 统一资源定位
  4. 使用雅虎的API便捷的创建天气预报程序
  5. python中fmod什么意思_Python fmod()用法及代碼示例
  6. C++ 数字三角形(动态规划)
  7. 计算几何之大圆包含小圆问题
  8. pngquant——一个好用的png压缩工具
  9. 【联邦学习FATE框架实战】(四)用FATE从零开始实现纵向线性回归
  10. 网络再现新的虐猫图片!!