[C++] 栈的压入、弹出序列
目录
- 例题描述
- 思路一:栈模拟法
- 代码实现一
- 代码实现二:优化精简版
- 思路二:下标替代栈 - 空间优化至O(1)
- 代码实现
例题描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出序列。
假设压入栈的所有数字均不相等。
例如:序列{1,2,3,4,5}
是某栈的压栈序列,序列{4,5,3,2,1}
是该压栈序列对应的一个弹出序列,但{4,3,5,1,2}
就不可能是该压栈序列的弹出序列。
思路一:栈模拟法
解决该问题需要借助一个辅助栈,把输入的第一个序列中的数字依次入栈,并按照第二个序列的顺序依次从该栈中弹出数字。
判断一个序列是不是栈的弹出序列规律:
- 如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。
- 如果下一个弹出的数字不在栈顶,则把压栈序列中还没有入栈的数字压入栈,直到把下一个需要弹出的数字压入栈顶为止。如果所有数字都压入栈后没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。
代码实现一
#include <iostream>
#include <stack>using namespace std;bool IsPopOrder(const int* pPush, const int* pPop, int length) {bool Possible = false;if (pPush == nullptr || pPop == nullptr)return false;const int* pNextPush = pPush;const int* pNextPop = pPop;std::stack<int> s;while (pNextPop - pPop < length) {while (s.empty() || s.top() != *pNextPop) {if (pNextPush - pPush < length) {s.push(*pNextPush);pNextPush++;}else {break;}}if (s.top() != *pNextPop)break;s.pop();pNextPop++;}if (s.empty() && pNextPush - pPush == length)Possible = true;return Possible;
}
代码实现二:优化精简版
bool IsPopOrder(vector<int> pushV,vector<int> popV) {stack<int> s;int i = 0, j = 0;while (i < pushV.size()) {s.push(pushV[i++]);while (!s.empty() && s.top() == popV[j]) {s.pop();j++;}}return s.size() == 0;
}
思路二:下标替代栈 - 空间优化至O(1)
利用size
下标在原压入序列数组进行模拟,压入与弹出对照操作,此时压入序列数组就相当于一个栈。这个实现方式和上面精简版大同小异,不过在下一个元素入栈位置的规划上有差别:
- 上一种方法
i
与s.top()
数据是分离的,所以入栈后直接给i++
即可。 - 此方法
size
即表示的是栈顶元素,故自增只能放在弹栈检查之后。对应代码⭐标注。
size >= 0
这条判断是为了控制溢出,否则持续向负数下标增长,产生了未定义行为,结果不可预期(有时不会出问题,有时会有问题,取决于这段空间之前存过什么值),所以避免此问题,需要直接限定在有效范围内。
最终返回size
是否为0
,即是否正确完全弹栈即可。
代码实现
bool IsPopOrder(vector<int> pushV, vector<int> popV) {int size = 0, j = 0;for (int e : pushV) {// 每次更新栈顶数据,一步“入栈”操作pushV[size] = e;// 若stack的顶部数据与popV出栈数字相同,则数据出栈while (size >= 0 && pushV[size] == popV[j]) {j++;size--; // 弹栈操作}size++; // 规划好下次入栈的槽位⭐}return size == 0;
}
测试
int main() {int a[] = { 1,2,3,4,5 };int b[] = { 4,3,5,2,1 };int c[] = { 4,3,5,1,2 };int size = sizeof(a) / sizeof(a[0]);if (IsPopOrder(a, b, size))cout << "Yes" << endl;elsecout << "No" << endl;if (IsPopOrder(a, c, size))cout << "Yes" << endl;elsecout << "No" << endl;system("pause");return 0;
}
输出结果
Yes
No
[C++] 栈的压入、弹出序列相关推荐
- 【剑指offer-Java版】22栈的压入弹出序列
栈的压入弹出序列:给定两个序列,一个是压入顺序,判断另外一个是否是该压入顺序的一个弹出顺序 思路:纯粹的模拟栈的压入和弹出顺序 分别遍历压栈序列seq1和另一个序列seq2 比较当前栈顶元素和seq2 ...
- 数据结构与算法--举例分析法- 栈的压入弹出序列
举例分析 与上两篇问中画图方法一样,我们可以用举例模拟的方法思考分析复杂问题.当一眼不能看出问题的规律的时候,我们可以用几个具体的例子来模拟一下问题的过程.这样就和我们在程序出现问题时候的debug一 ...
- 剑指offer-21.栈的压入弹出序列
1.题目 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...
- python 栈的压入弹出序列
| 栈的压入和弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序, 请判断第二个序列是否为该栈的弹出顺序. 假设压入栈的所有数字均不相等. 例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序 ...
- 剑指offer 31.栈的、压入弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是 ...
- 剑指Offer(Java实现)栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 ...
- 剑指Offer--022-栈的压入、弹出序列
链接 牛客OJ:栈的压入.弹出序列 九度OJ:http://ac.jobdu.com/problem.php?pid=1366 GitHub代码: 022-栈的压入弹出序列 CSDN题解:剑指Offe ...
- 剑指offer22:栈的压入、弹出序列
题意: 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2, ...
- 举例让抽象问题具体化:栈的压入、弹出序列
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一 ...
- 剑指Offer之栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入书序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相同.例如1.2.3.4.5是某栈的压入序列,序列5.4.3.2.1是该栈对应的一 ...
最新文章
- windows性能计数器搜集方法
- 资料分享:送你一本《数据结构(C#语言版)》电子书!
- Oracle的介绍及其在安装和使用Oracle过程中可能遇到的困难及其相应的解决措施
- CUDA从入门到精通(三):必备资料
- 日期时间选择器-jeDate日期控件
- Facebook 开源了一整套重要的 Linux 内核组件与工具!
- win7 IE11卸载后无法上网
- 让我去健身的不是漂亮小姐姐,居然是贝叶斯统计
- Javascript、Jquery获取浏览器和屏幕各种高度宽度
- INNO SETUP卸载程序中加入自定义窗体
- arraylist输出 java_在java中打印ArrayList时输出不同
- JavaSE基础(8)——Java内部类
- guid分区怎么装win7_gpt分区无法安装win7原因分析及解决方法(完美解决)
- 【C++】模拟String,柔性数组,运算符重载,写实拷贝
- 背景图页面缩小会变形_CSS背景图拉伸不变形
- 360cdn能挡住cc攻击_又被CC攻击弄得心有余悸?莫怕!这里教你如何防御
- 本地git的分支名称变空的处理方法
- Goldsrc 地图 BSP 文件格式规范
- arm架构 CF-WU810N网卡驱动安装经验
- 基于淘宝开源Tair分布式KV存储引擎的整合部署