剑指Offer--022-栈的压入、弹出序列
链接
牛客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( );}};
发现规律
这个是看到的别人的做法
不一样的思路:
我先取出pop序列的第一个(比如pop【3,2,4,5,1】),在push序列中找到这个位置,push【1,2,3,4,5】,
此时我们找到了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-栈的压入、弹出序列相关推荐
- 【LeetCode】剑指 Offer 31. 栈的压入、弹出序列
[LeetCode]剑指 Offer 31. 栈的压入.弹出序列 文章目录 [LeetCode]剑指 Offer 31. 栈的压入.弹出序列 package offer;import java.uti ...
- 【剑指offer-Java版】22栈的压入弹出序列
栈的压入弹出序列:给定两个序列,一个是压入顺序,判断另外一个是否是该压入顺序的一个弹出顺序 思路:纯粹的模拟栈的压入和弹出顺序 分别遍历压栈序列seq1和另一个序列seq2 比较当前栈顶元素和seq2 ...
- 剑指Offer之栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入书序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相同.例如1.2.3.4.5是某栈的压入序列,序列5.4.3.2.1是该栈对应的一 ...
- 剑指offer:栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...
- 剑指OFFER之栈的压入、弹出序列(九度OJ1366)
题目描述: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...
- 《剑指offer》-- 栈的压入与弹出序列、把字符串转化为整数、扑克牌顺子、孩子们的游戏(圆圈中最后剩下的数)
一.栈的压入与弹出序列: 1.题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序. 假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序 ...
- 剑指offer(21):栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应 ...
- 《剑指offer》栈的压入、弹出序列
题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对 ...
- 剑指Offer 31 栈的压入、弹出序列
栈的压入.弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2 ...
- java输出栈的弹出序列_剑指offer:栈的压入、弹出序列(Java)
1.题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 ...
最新文章
- 硬盘盘符双击无法打开,只能右键打开(解决方法)(转载)
- tc写入txt成功却没有内容_挖洞经验 | 构造UserAgent请求头内容实现LFI到RCE提权
- ALV添加文字输入框
- 第三章 用户界面设计
- python用于数据分析的案例_Python数据分析经典案例
- 北漂周记--第2记--培训开始
- python list方法操作_Python 列表(List)操作方法详解
- mysql 5.7 数据库备份_mysql 5.7 数据库备份
- 计算机网络cr什么意思,网络用语cr是什么意思
- LoadRunner 12 发布,主推云
- win7计算机锁频图片怎么设置,Win7系统怎么使用注册表设置锁屏壁纸的图文教程...
- 央视就《新闻联播》“火炬手空手捐款”致歉
- Android在线购物商城 app端+后台
- 7-1 房屋分拆 (25 分)(C语言版)
- 从零开始写CMOS摄像头驱动(一)
- 为您员工远程工作执行BYOD策略保驾护航
- 模拟通讯录系统2.0
- DophinScheduler server部分 核心代码详细解析——掌控任务和进程的呼吸与脉搏:log、monitor与registry
- 【SDCC 2016】蘑菇街、华为、阿里巴巴、58到家、同程旅游、链家网、京东的架构变迁与技术演进...
- Android12.0 默认开启WLAN热点设置默认热点名称和密码