Skip to content

Commit

Permalink
添加《剑指Offer》第22题 栈的压入、弹出序列
Browse files Browse the repository at this point in the history
  • Loading branch information
amusi committed Jul 29, 2018
1 parent 7250ec3 commit 210f898
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 41 deletions.
80 changes: 40 additions & 40 deletions Coding Interviews/21_MinInStack/MinInStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ Date: 2018-07-11
// 方法1:数据栈和辅助栈相同容量
class Solution {
public:
????// 题目描述: 包含min函数的栈
// 题目描述: 包含min函数的栈
// 方法:
// 自定义两个栈
stack<int> dataStack; // 数据栈
stack<int> helpStack; // 辅助栈

// 压入元素 O(1)
????void push(int value) {
void push(int value) {
dataStack.push(value);
if (helpStack.empty()){
helpStack.push(value);
Expand All @@ -30,58 +30,58 @@ class Solution {
helpStack.push(helpStack.top());
}
}
????}
????
}
// 弹出元素 O(1)
????void pop() {
void pop() {
if(dataStack.empty() || helpStack.empty())
return;
dataStack.pop();
helpStack.pop();
????}
}
// 返回栈顶元素 O(1)
????int top() {
int top() {
return dataStack.top();
????}
????
}
// 返回栈中最小元素 O(1)
????int min() {
int min() {
return helpStack.top();
????}
?????
}
};


// 方法2 数据栈容量大于辅助栈容量
class Solution {
public:
?????
????stack<int> stack1,stack2;
?????
????void push(int value) {
????????stack1.push(value);
????????if(stack2.empty())
????????????stack2.push(value);
????????else if(value<=stack2.top())
????????{
????????????stack2.push(value);
????????}
????}
?????
????void pop() {
stack<int> stack1,stack2;
void push(int value) {
stack1.push(value);
if(stack2.empty())
stack2.push(value);
else if(value<=stack2.top())
{
stack2.push(value);
}
}
void pop() {
// 判断两个栈顶元素是否相等
????????if(stack1.top()==stack2.top())
????????????stack2.pop();
????????stack1.pop();
?????????
????}
?????
????int top() {
????????return stack1.top();???????
????}
?????
????int min() {
????????return stack2.top();
????}
?????
if(stack1.top()==stack2.top())
stack2.pop();
stack1.pop();
}
int top() {
return stack1.top();
}
int min() {
return stack2.top();
}
};
84 changes: 84 additions & 0 deletions Coding Interviews/22_StackPushPopOrder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# 题目描述

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

# 解题思路

考查知识点:

- [栈(Stack)知识点](https://github.com/amusi/coding-note/blob/master/Coding%20Interviews/07_QueueWithTwoStacks/QueueStack.md)
- [C++ STL::Stack用法](http://www.cplusplus.com/reference/stack/stack/)
- [Python list用法](https://docs.python.org/3.8/c-api/list.html)

一开始看到这个题目,觉得很简单。以为是一下子入栈,然后出栈,所以理所当然以为直接判断第一个序列和第二个序列是否是逆序关系。但结果发现是我太单纯了,题目都没有读懂。

为了方便描述,这里定义第一个序列(压入栈)为pushV,第二个序列(弹出栈)为popV。

本题的关键考查对栈(stack)的掌握,其特点是先入后出,返回栈顶元素。

解决此问题的技巧在于,**构建一个辅助栈stack**。该辅助栈stack就是来模拟pushV的弹出情况是否能和popV一致。如果一致,则表示pushV和popV是满足"栈的压入、弹出序列"关系的,否则,不满足关系。

通过将pushV的元素依次压入到stack中,在每压入新元素时,需要将stack栈顶元素与popV栈顶元素进行比较。如果相同,则将stack和popV栈顶元素都弹出;如果不同,则继续压入新元素。当把pushV序列中所有元素压入stack,并进行stack和popV栈顶严元素比较后,判断此时stack是否为空的情况。

如果stack为空,则表示辅助栈stack与popV序列对应关系一致,即pushV和popV是满足"栈的压入、弹出序列"关系的,否则,不满足关系。



# 代码

[C++](StackPushPopOrder.cpp)

```c++
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
// 判断输入
if(pushV.size() == 0)
return false;
// 添加辅助栈
vector<int> stack; // 辅助栈的目的是与popV进行对比
for(int i=0,j=0; i<pushV.size();){
//
stack.push_back(pushV[i++]); // 向辅助栈压入pushV元素
// 两个条件缺一不可
// 条件1: 弹出的数量小于或等于序列长度
// 条件2: 辅助栈的栈顶元素与对应的popV序列元素值相等
while(j < popV.size() && stack.back() == popV[j]){
stack.pop_back(); // 弹出辅助栈顶元素
++j; // popV序列下一个元素索引
}
}
return stack.empty();
}
};
```
[Python](StackPushPopOrder.py)
```python
# -*- coding:utf-8 -*-
class Solution:
def IsPopOrder(self, pushV, popV):
# 判断输入
if len(pushV) == 0:
return False
# 添加辅助栈
stack = []
j = 0
for i in range(0, len(pushV)):
# 向辅助栈添加pushV元素
stack.append(pushV[i])
# 两个条件缺一不可
# 条件1: 弹出的数量小于或等于序列长度
# 条件2: 辅助栈的栈顶元素与对应的popV序列元素值相等
while j<len(popV) and stack[-1]==popV[j]:
stack.pop() # 弹出辅助栈顶元素
j+=1 # popV序列下一个元素索引
if len(stack) == 0:
return True
return False
```

# 参考

https://www.nowcoder.com/questionTerminal/d77d11405cc7470d82554cb392585106
34 changes: 34 additions & 0 deletions Coding Interviews/22_StackPushPopOrder/StackPushPopOrder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*****************************************
Copyright: Amusi
Author: Amusi
Date: 2018-07-29
题目描述
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。
例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
*****************************************/

class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
// 判断输入
if(pushV.size() == 0)
return false;
// 添加辅助栈
vector<int> stack; // 辅助栈的目的是与popV进行对比
for(int i=0,j=0; i<pushV.size();){
//
stack.push_back(pushV[i++]); // 向辅助栈压入pushV元素
// 两个条件缺一不可
// 条件1: 弹出的数量小于或等于序列长度
// 条件2: 辅助栈的栈顶元素与对应的popV序列元素值相等
while(j < popV.size() && stack.back() == popV[j]){
stack.pop_back(); // 弹出辅助栈顶元素
++j; // popV序列下一个元素索引
}
}
return stack.empty();
}
};
38 changes: 38 additions & 0 deletions Coding Interviews/22_StackPushPopOrder/StackPushPopOrder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'''
Copyright: Amusi
Author: Amusi
Date: 2018-07-11
题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度都是O(1)。
'''

# -*- coding:utf-8 -*-
class Solution:

def __init__(self):
self.data_stack = []
self.help_stack = []
# 压入新元素
def push(self, node):
self.data_stack.append(node)
if len(self.help_stack)==0:
self.help_stack.append(node)
else:
if node < self.help_stack[-1]:
self.help_stack.append(node)
else:
self.help_stack.append(self.help_stack[-1])
# 弹出栈顶元素
def pop(self):
self.data_stack.pop()
self.help_stack.pop()

# 返回栈顶元素
def top(self):
return self.data_stack[-1]

# 返回当前栈中最小元素
def min(self):
return self.help_stack[-1]
2 changes: 1 addition & 1 deletion Coding Interviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@

- [x] **【面试题21:包含min函数的钱】** [MinInStack](21_MinInStack)

- [ ] **【面试题22:栈的压入、弹出序列】**
- [x] **【面试题22:栈的压入、弹出序列】** [StackPushPopOrder](22_StackPushPopOrder)

- [ ] **【面试题23:从上往下打印二叉树】**

Expand Down

0 comments on commit 210f898

Please sign in to comment.