Given a stack which can keep $M$ numbers at most. Push $N$ numbers in the order of 1, 2, 3, …, $N$ and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if $M$ is 5 and $N$ is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): $M$ (the maximum capacity of the stack), $N$ (the length of push sequence), and $K$ (the number of pop sequences to be checked). Then $K$ lines follow, each contains a pop sequence of $N$ numbers. All the numbers in a line are separated by a space.
For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
YES
NO
NO
YES
NO
本题 25 分,模拟堆栈入栈出栈过程,难度较大,考虑的细节问题比较多,核心问题是抓住哪组数据在进行比较,入栈队列、待判断的出栈队列和空堆栈之间是什么关系。
首先,新建一个空的堆栈,模拟整个入栈出栈的过程。入栈顺序与数据由入栈队列一步一步无脑给出,因此外层一个大的循环。
堆栈要与待判断的出栈队列相比较。自然,直接看堆栈看到的是入栈的顺序,题目是对比的出栈顺序,因此必然要用到pop()
,出栈队列依次与弹出的元素相比较,完全符合且当入栈的大循环结束后堆栈为空,那么打印YES
。然而使用pop()
来比较有诸多不便,大部分堆栈的pop()
方法是不返回值,那么应该使用top()
方法取得栈顶元素,如果栈顶元素满足上述要求,那么执行pop()
。
弹出元素后要以出栈队列的下一个元素为基准,继续判断。因此出栈队列元素需要有一个指针来标注当前的基准元素,最初指针为0,在pop()
后指针+1。弹出元素后指针和栈顶元素都不同了,那么就存在这时的栈顶元素可能会满足更新后的基准元素,那么应该继续弹出,指针继续+1,直到二者不相等。那么这样的过程就可以用while
语句描述,构成内部的一个循环。
需要指出的是,涉及到堆栈时,一定要考虑两个边界问题。第一,栈是否为空,若为空,那么无法执行pop()
/top()
指令;第二,栈是否有容量,容量为多大,若当前的size()
超过了栈的容量,那么无法执行push()
指令。
有了这两个边界问题,再来看上面的分析过程。
while
循环中涉及到pop()
,那么就要有个判空的条件,只要堆栈不空,那么循环可以继续,否则,循环终止。push()
,那么压栈后若堆栈size()
大于容量,就说明无法模拟待判断的出栈顺序,直接返回非。在大循环结束后,也就是元素全部入栈后,要对堆栈判空。如果堆栈是空的,说明入栈的所有元素已经按照待判断的出栈顺序依次pop()
,可以打印YES
,否则,说明堆栈现有的元素顺序无法满足,因此堆在堆栈里弹不出去,打印NO
。另外一个角度,判断出栈队列的指针也是等价的。如果出栈队列的指针越界,那么说明待比较的元素都已经找到满足要求的入栈元素,此时堆栈为空。
class Stack(object):
def __init__(self):
self.stack = []
def push(self, data):
self.stack.append(data)
def pop(self):
return self.stack.pop()
def top(self):
return self.stack[-1]
def size(self):
return len(self.stack)
def empty(self):
return not bool(self.stack)
def judge(cap, std, ins):
ptr = 0
for e in std:
s.push(e)
if s.size() > cap:
return False
while (not s.empty()) and (s.top() == ins[ptr]):
p = s.pop()
ptr += 1
if s.empty():
return True
else:
return False
m, n, count = map(int, input().split())
std = [i+1 for i in range(n)]
for _ in range(count):
s = Stack()
ins = list(map(int, input().split()))
if judge(m, std, ins):
print('YES')
else:
print('NO')
https://blog.csdn.net/Wonz5130/article/details/79894496
https://blog.csdn.net/lianwaiyuwusheng/article/details/83543999
https://www.liuchuo.net/archives/2232