其他栈相关问题
来源:互联网 发布:js获取对象数组的长度 编辑:程序博客网 时间:2024/06/03 18:05
1. 包含min函数的栈
来源
leetcode155 https://leetcode.com/problems/min-stack/
剑指offer21
Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.push(x) -- Push element x onto stack.pop() -- Removes the element on top of the stack.top() -- Get the top element.getMin() -- Retrieve the minimum element in the stack.注:这几个函数要在常数时间内完成。
思路:push,pop,top正常来说肯定是常数时间内的,但是如何让getMin也能保持在常数时间呢。
单独维护一个单调递减栈来存储栈中最小值。
class MinStack { Deque<Integer> deque = new ArrayDeque<Integer>(); Deque<Integer> minDeque = new ArrayDeque<Integer>(); public void push(int x) { deque.add(x); if(minDeque.size() == 0 || x <= minDeque.peekLast()) minDeque.add(x); } public void pop() { int x = deque.pollLast(); if(x == minDeque.peekLast()) minDeque.pollLast(); } public int top() { return deque.peekLast(); } public int getMin() { return minDeque.peekLast(); }}
2. 用两个栈实现队列
维护两个栈,每次Push进一个栈中,每次getHead从另一个栈中取,当取栈空了,则将push栈中的弹入取栈中。这样保证了先进的一定比后进的先出。弹出元素的平均时间复杂度O(1)
class QueueImpl { Deque<Integer> deque_push = new ArrayDeque<Integer>(); Deque<Integer> deque_pop = new ArrayDeque<Integer>(); public void push(int x) { deque_push.add(x); } public int getHead() { if(deque_pop.size() == 0){ while(deque_push.size() != 0) deque_pop.add(deque_push.pollLast()); } return deque_pop.pollLast(); }}
3. 用两个队列实现栈
维护两个队列,每次向有元素的队列压入元素(两个队列会交替压入),每次弹出元素时要将有元素队列中的元素放入另一个队列中,留下一个元素在原来的队列弹出。弹出的平均时间复杂度O(n)。
class StackImpl { Deque<Integer> deque1 = new ArrayDeque<Integer>(); Deque<Integer> deque2 = new ArrayDeque<Integer>(); public void push(int x) { Deque<Integer> deque = deque1.size() == 0 ? deque2 : deque1; deque.add(x); } public int pop() { Deque<Integer> deque_pop = deque1.size() == 0 ? deque2 : deque1; Deque<Integer> deque_push = deque1.size() == 0 ? deque1 : deque2; while(deque_pop.size() > 1) deque_push.add(deque_pop.pollLast()); return deque_pop.pollLast(); }}
4. 用一个数组实现两个栈
说明如何用一个数组A[1..n]来实现两个栈,使得两个栈中的元素总和不到n时,两个都不会发生上溯。注意PUSH和POP操作的时间应为O(1)
思路:两个栈从数组的前后开始向中间存储。
class Stack { int[] arr; int flag1 = -1, flag2 = -1; public Stack(n){ arr = new int[n]; flag2 = n; } public void push1(int x) { if(flag1 == (flag2 - 1)) return; arr[++flag1] = x; } public void push2(int x) { if(flag1 == (flag2 - 1)) return; arr[--flag2] = x; } public int pop1() { if(flag1 > -1) return arr[flag1--]; } public int pop2() { if(flag2 < n) return arr[flag2++]; }}
思考:用一个数组实现三个栈呢。
可以使用交叉索引,像上一题存两个栈的话,一个栈可以存储在0,2,4,6…/另一存储在1,3,5,7…
若三个栈就可以存储成0,3,6,9…./1,4,7,10…/2,5,8,11….
若还沿用上题方法,可以将第三个栈存储为:mid, mid+1, mid-1, mid+2, mid-2这样对称存储。
5. 栈对递归思想的考察
翻转栈中所有元素,要求额外空间复杂度o(1)
用递归来实现(与汉诺塔思想类似)
首先弹出栈顶元素top1,将剩余n-1栈递归反转,反转后弹出当前栈顶元素top2,再递归反转n-2栈。
放入top1元素,反转n-1栈。
最后放入top2元素。
public void reverseStack(Deque<Integer> deque){ if(deque.size() == 0) return; int top1 = deque.pollLast(); reverseStack(deque); if(deque.size() == 0) deque.add(top1); else{ int top2 = deque.pollLast(); reverseStack(deque); deque.add(top1); reverseStack(deque); deque.add(top2); }}
-给栈中元素排序
类似冒泡排序的递归思想,每次将最小的值弹到栈顶,然后从下一个元素开始进行下轮的冒泡递归
public void sortStack(Deque<Integer> deque){ if(deque.size() == 0) return; int top1 = deque.pollLast(); sortStack(deque); if(deque.size() == 0) deque.add(top1); else{ int top2 = deque.pollLast(); if(top1 <= top2) { deque.add(top2); deque.add(top1); } else{ deque.add(top1); sortStack(deque); deque.add(top2); } }}
- 其他栈相关问题
- QLB相关的其他问题(云相关)
- LDA-线性判别分析(四)其他几个相关问题
- 4-10 和堆相关的其他问题
- 其他问题?
- 其他相关的参数。。
- 其他_postgreSQL相关
- 其他_mongoDB相关
- 其他字符集相关
- Redis其他相关命令
- 应聘Java笔试时可能出现问题及其答案 (其他相关)
- ArcGIS 10.0简单安装方法及ArcGIS其他组件使用相关问题
- 字符串的排列与组合及八皇后等其他相关问题
- 栈的相关问题
- Graphics相关-GradientDrawable以及其他
- [openstack swift]3 其他相关
- Graphics相关-GradientDrawable以及其他
- Extjs-布局-其他相关知识
- CMake使用总结
- 树状数组区间求和三种模型
- 编译vlc for ios
- (转)C#之委托及事件
- openstack架构简介J版(更新中)
- 其他栈相关问题
- Advanced Custom Fields – 超级wordpress自定义字段插件
- IO scheduler
- 第14周 【项目1 - 小玩文件】(1)(2)
- 隐马尔科夫模型(HMM)攻略
- java虚拟机:java的平台无关性,安全性和网络移动性
- 一个简单的保存string 到 txt 中的方法,流的运用要注意
- 如何在VS2013中配置一个DirectX开发环境
- 2.list和tuple