面试算法:计算堆栈当前元素的最大值
2017-02-24 10:11
405 查看
更详细的讲解和代码调试演示过程,请参看视频
如何进入google,算法面试技能全面提升指南
有一道堆栈相关算法题,我被面试过两次以上,看似其在算法面试中出现的概率很高,由此值得我们好好分析下。题目是这样的:
对于堆栈的常用操作有, pop 弹出堆栈顶部的元素;push 向堆栈压入一个元素;peek 获得堆栈顶部的元素值,但不弹出堆栈。现在要去你增加一个操作max, 它的作用是返回堆栈当前所有元素中值最大的那个,例如堆栈当前元素有:
stack: 5,4,2,3
那么max() 返回的值就是5. 假设向堆栈继续推入元素后,情况如下:
stack: 5, 4, 2, 3, 6, 1, 10, 8
那么调用max() 得到的元素为10.
假设我们现在我们采取pop操作,弹出顶部两个元素,那么堆栈情况如下:
stack: 5, 4, 2, 3, 6, 1
显然此时max 操作返回的元素是6。
请给出一个时间复杂度为O(1)的算法,实现max操作。
这道题一个麻烦处在于,如果堆栈仅仅是压入元素,那么返回最大值是很容易的,只要把当前压入元素的最大值记下来就可以了。问题在于,堆栈还有弹出操作,当弹出后,堆栈当前的最大元素可能就会不断的发生变化。如果是压入操作和弹出操作交替进行的话,那么情况就更复杂了。
解决这个问题的算法如下:
1, 每次压入元素是,用一个变量maxVal, 记录堆栈当前元素的最大值。
2, 创建一个新堆栈maxStack,当压入元素的值大于当前元素的最大值时,把该元素压入maxStack.
3, 弹出一个元素时,如果弹出的元素是当前最大值,那么把maxStack顶部的元素也弹出,然后把maxValue设置成maxStack的顶部元素。
4,执行max()操作时,可以直接返回maxValue, 或是maxStack堆栈的顶部元素。
不难看出,上述操作使得元素压入时,maxValue 与 maxStack顶部元素保持一致,当元素弹出时,如果弹出的是当前最大值,那么步骤3把maxValue的值设置成maxStack的顶部元素,因此,无论是压入还是弹出操作,maxValue与maxStack的始终保持一致。
同时,当只有压入元素大于当前堆栈元素的最大值时,新元素才会压入maxStack,这就保证了maxStack堆栈顶部的元素就是当前堆栈中所有元素最大的一个。
上面算法,执行max()操作时,只需要把maxStack顶部元素弹出或直接返回maxValue,因此时间复杂度是O(1), 在特殊情况下,例如所有元素是升序压入堆栈的,比如压入的元素为:1,2, 3, 4.那么这些元素除了压入正常堆栈外,还得全部压入maxStack, 因此算法的空间复杂度是O(N).
我们看看具体代码的实现:
代码实现简单,基本上根据算法步骤来实现,我们再看看主入口处的代码:
运行结果如下:
稍微检测下便可以发现,代码给出的结果是正确的,更多更详实的讲解和调试演示过程,请大家参考视频。
更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
如何进入google,算法面试技能全面提升指南
有一道堆栈相关算法题,我被面试过两次以上,看似其在算法面试中出现的概率很高,由此值得我们好好分析下。题目是这样的:
对于堆栈的常用操作有, pop 弹出堆栈顶部的元素;push 向堆栈压入一个元素;peek 获得堆栈顶部的元素值,但不弹出堆栈。现在要去你增加一个操作max, 它的作用是返回堆栈当前所有元素中值最大的那个,例如堆栈当前元素有:
stack: 5,4,2,3
那么max() 返回的值就是5. 假设向堆栈继续推入元素后,情况如下:
stack: 5, 4, 2, 3, 6, 1, 10, 8
那么调用max() 得到的元素为10.
假设我们现在我们采取pop操作,弹出顶部两个元素,那么堆栈情况如下:
stack: 5, 4, 2, 3, 6, 1
显然此时max 操作返回的元素是6。
请给出一个时间复杂度为O(1)的算法,实现max操作。
这道题一个麻烦处在于,如果堆栈仅仅是压入元素,那么返回最大值是很容易的,只要把当前压入元素的最大值记下来就可以了。问题在于,堆栈还有弹出操作,当弹出后,堆栈当前的最大元素可能就会不断的发生变化。如果是压入操作和弹出操作交替进行的话,那么情况就更复杂了。
解决这个问题的算法如下:
1, 每次压入元素是,用一个变量maxVal, 记录堆栈当前元素的最大值。
2, 创建一个新堆栈maxStack,当压入元素的值大于当前元素的最大值时,把该元素压入maxStack.
3, 弹出一个元素时,如果弹出的元素是当前最大值,那么把maxStack顶部的元素也弹出,然后把maxValue设置成maxStack的顶部元素。
4,执行max()操作时,可以直接返回maxValue, 或是maxStack堆栈的顶部元素。
不难看出,上述操作使得元素压入时,maxValue 与 maxStack顶部元素保持一致,当元素弹出时,如果弹出的是当前最大值,那么步骤3把maxValue的值设置成maxStack的顶部元素,因此,无论是压入还是弹出操作,maxValue与maxStack的始终保持一致。
同时,当只有压入元素大于当前堆栈元素的最大值时,新元素才会压入maxStack,这就保证了maxStack堆栈顶部的元素就是当前堆栈中所有元素最大的一个。
上面算法,执行max()操作时,只需要把maxStack顶部元素弹出或直接返回maxValue,因此时间复杂度是O(1), 在特殊情况下,例如所有元素是升序压入堆栈的,比如压入的元素为:1,2, 3, 4.那么这些元素除了压入正常堆栈外,还得全部压入maxStack, 因此算法的空间复杂度是O(N).
我们看看具体代码的实现:
import java.util.Stack; public class MaxStack { private Stack<Integer> stack = new Stack<Integer>(); private int maxVal = Integer.MIN_VALUE; private Stack<Integer> maxStack = new Stack<Integer>(); public void push(int val) { if (val >= maxVal) { maxVal = val; maxStack.push(maxVal); } stack.push(val); } public int peek() { return stack.peek(); } public int pop() { if (stack.peek() == maxVal) { maxStack.pop(); } maxVal = maxStack.peek(); return stack.pop(); } public int max() { return maxStack.peek(); } }
代码实现简单,基本上根据算法步骤来实现,我们再看看主入口处的代码:
public class StackAndQuque { public static void main(String[] args) { MaxStack ms = new MaxStack(); ms.push(5); ms.push(4); ms.push(2); ms.push(3); System.out.println("Max Val in stack is : " + ms.max()); ms.push(6); ms.push(1); ms.push(10); ms.push(8); System.out.println("Max Val in stack is : " + ms.max()); ms.pop(); ms.pop(); System.out.println("Max Val in stack is : " + ms.max()); ms.push(7); System.out.println("Max Val in stack is : " + ms.max()); } }
运行结果如下:
Max Val in stack is : 5 Max Val in stack is : 10 Max Val in stack is : 6 Max Val in stack is : 7
稍微检测下便可以发现,代码给出的结果是正确的,更多更详实的讲解和调试演示过程,请大家参考视频。
更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
相关文章推荐
- 风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。 假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。 设计算法,计算你能获得的最大收益。 输入数值范围:2<=n<
- 面试算法:用队列计算滑动窗口内的最大网络流量
- 面试算法:利用堆栈计算逆向波兰表达式
- 面试算法:堆栈元素的在线排序
- 【算法】从第一个元素开始,计算累和的最大值
- 面试算法:利用堆栈计算逆向波兰表达式
- 这是一个我面试某公司的算法题目:对一个字符数组进行排序,根据给定的字符,大于它的,放在数组的左边,小于它的,放在数组的右边,且数组中的元素之间的相对位置要保持不变。
- 计算当前年份的月数的最大天数
- 计算最大公约数的算法
- 大学时候想的一个算法——计算数组中最大和序列
- 微软等数据结构+算法面试100题(46)-- 查找最小的k 个元素
- 【每日面试题】求一个矩阵中最大的二维矩阵(元素和最大)
- n个元素的数组中找出前K个最大数最有效算法O(nlg(k))
- C/C++面试之算法系列--寻找最大公共子字符串
- 微软等数据结构+算法面试100题(38)-- 二叉树中任意两个节点间的最大距离
- 微软等数据结构+算法面试100题(40)-- 旋转数组中的最小元素
- 数据结构 算法面试100题 之 逐层遍历二叉树元素
- 【扫描算法】求一个向量的元素和最大的连续子向量 --编程珠玑
- 大学时候想的一个算法——计算数组中最大和序列
- 计算一个整形数组里的连续元素和的最大值