【剑指Offer】面试题:栈和队列

剑指Offer中一共有4道关于栈和队列的面试题

面试题9:用两个栈来实现队列

题目描述:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

详情见:【剑指Offer】面试题9:用两个栈实现队列——JS实现

面试题30:包含min函数的栈

题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数。在该栈中,调用min、push及pop的时间复杂度应都是O(1)。

思路:(建立辅助栈,记录每次数据栈发生变化后的最小值)

push 函数:将数值压入数据栈;同时把每次的最小元素(之前的最小元素和新压入栈的元素两者的较小值)都保存在另一个辅助栈里(如果此时辅助栈为空或数值比辅助栈的栈顶元素小,则再将此数值压入辅助栈,否则向辅助栈中压入其本身的栈顶元素)。

pop 函数:如果数据栈和辅助栈都不为空,则分别弹出栈顶元素。

min 函数:如果数据栈和辅助栈都不为空,则返回辅助栈的栈顶元素。

面试题31:栈的压入、弹出序列

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

思路:(建立辅助栈,举例分析发现规律)如果下一个要弹出的数字刚好是栈顶数字,那么直接弹出;如果下一个要弹出的数字不在栈顶,则把压栈序列中还没入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止;如果所有数字都压入栈后仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。

面试题59:队列的最大值

题目一、滑动窗口的最大值

题目描述:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路:(两端开口的队列)我们借助一个两端开口的队列,用来保存有可能是滑动窗口最大值的数字的下标。在存入一个数字的下标之前,首先要判断队列里已有数字是否小于待存入的数字。如果已有数字小于待存入的数字,那么这些数字已经不可能是滑动窗口的最大值,因此它们将会被依次从队列的尾部删除。同时,如果队列头部的数字已经从窗口滑出,那么滑出的数字也需要从队列的头部删除。这样,队列头部的数字就是每次滑动窗口的最大值。

题目二、队列的最大值

题目描述:请定义一个队列并实现函数max得到队列里的最大值,要求函数max、push_back、pop_front的时间复杂度都是O(1)。

思路:(两端开口的队列)我们借助一个两端开口的队列(辅助队列),用来保存有可能是队列中最大值的数字和下标;和一个变量下标索引。

push函数:在向辅助队列中存入一个数字及其下标之前,首先要判断辅助队列里已有数字是否小于待存入的数字。如果已有数字小于待存入的数字,那么这些数字已经不可能是队列的最大值,因此它们将会被依次从辅助队列的尾部删除。

之后,再将数字及其下标存入队列尾部和辅助队列的尾部,并将下标索引加一。

pop函数:如果队列头部的下标和辅助队列头部的下标相等,则同时将头部都删除。否则只删除队列的头部。

max函数:如果辅助队列不为空,则返回辅助队列头部的数字。

END

猜你喜欢

转载自blog.csdn.net/Dora_5537/article/details/90772132