【剑指offer】33.栈的压入、弹出序列

总目录:

算法之旅导航目录

 

1.问题描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
1. 0<=pushV.length == popV.length <=1000
2. -1000<=pushV[i]<=1000
3. pushV 的所有数字均不相同

 

2.问题分析

 1压栈弹栈,检查不合理之处:当前弹出元素的下一个元素,如果既不是当前的栈顶(可弹出元素),也不是待压入元素,则错误

2压栈改良版,主要是浓缩压栈逻辑,要么压栈到和当前弹出的元素匹配,要么就压完为止

3原地栈,直接用数组索引来判断,暂时未看懂


3.代码实例

压栈弹栈

 1 class Solution {
 2   public:
 3     stack<int> st;
 4     int getItemIndex(vector<int>& vec, int val) {
 5         int itemLength = vec.size();
 6         for (int i = 0; i < itemLength; i++) {
 7             if (vec[i] == val) {
 8                 return i;
 9             }
10         }
11 
12         //不存在的元素
13         return -1;
14     }
15 
16     bool IsPopOrder(vector<int> pushV, vector<int> popV) {
17         //二者长度是否一致
18         if (pushV.size() != popV.size()) {
19             return false;
20         }
21 
22         int itemNum = pushV.size();
23         int curPushIndex = -1;
24         int curItemRawIndex = 0;
25 
26         //逐元素检查弹出数据是否合理
27         for (int i = 0; i < itemNum; i++) {
28             //获取当前弹出元素在原集合中的索引
29             curItemRawIndex = getItemIndex(pushV, popV[i]);
30             if (curItemRawIndex < 0) {
31                 return false;
32             }
33 
34             //如果已经检查至最后一个,则不必继续进行
35             if ((i + 1) >= itemNum) {
36                 return true;
37             }
38 
39             //将尚未压入内容全部压栈
40             if (curItemRawIndex > curPushIndex) {
41                 for (int j = curPushIndex + 1; j <= curItemRawIndex; j++) {
42                     st.push(pushV[j]);
43                 }
44 
45                 //更新当前压入索引
46                 curPushIndex = curItemRawIndex;
47             }
48 
49             //因为当前元素已经进入了弹出队列
50             st.pop();
51 
52             //检查下一个弹出元素是否合理
53             //不合理情况:既不等于下一个可弹出元素,也不等于尚未压入元素
54             int nextItemRawIndex = getItemIndex(pushV, popV[i + 1]);
55             if (popV[i + 1] != st.top() &&
56                     nextItemRawIndex <= curPushIndex) {
57                 return false;
58             }
59         }
60 
61         return true;
62     }
63 };
View Code

压栈改良版

 1 class Solution {
 2 public:
 3     bool IsPopOrder(vector<int> pushV,vector<int> popV) {
 4         int n = pushV.size();
 5         //辅助栈
 6         stack<int> s;
 7         //遍历入栈的下标
 8         int j = 0;
 9         //遍历出栈的数组
10         for(int i = 0; i < n; i++){
11             //入栈:栈为空或者栈顶不等于出栈数组
12             while(j < n && (s.empty() || s.top() != popV[i])){
13                 s.push(pushV[j]);
14                 j++;
15             }
16             //栈顶等于出栈数组
17             if(s.top() == popV[i])
18                 s.pop();
19             //不匹配序列
20             else
21                 return false;
22         }
23         return true;
24     }
25 };
View Code

原地栈

 1 class Solution {
 2 public:
 3     bool IsPopOrder(vector<int> pushV,vector<int> popV) {
 4         //表示栈空间的大小,初始化为0
 5         int n = 0;
 6         //出栈序列的下标
 7         int j = 0;
 8         //对于每个待入栈的元素
 9         for(int num : pushV){
10             //加入栈顶
11             pushV[n] = num;
12             //当栈不为空且栈顶等于当前出栈序列
13             while(n >= 0 && pushV[n] == popV[j]){
14                 //出栈,缩小栈空间
15                 j++;
16                 n--;
17             }
18             n++;
19         }
20         //最后的栈是否为空
21         return n == 0;
22     }
23 };
View Code

 

posted @ 2022-11-14 20:55  啊原来是这样呀  阅读(32)  评论(0编辑  收藏  举报