《程序员代码面试指南》第一章 栈和队列
来源:互联网 发布:梦里花落知多少网王txt 编辑:程序博客网 时间:2024/05/17 06:06
1、设计一个有getMin
功能的栈
LeetCode对应题目 155. Min Stack
实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作。
华为2017校招的一个题目就是实现一个有getMin
和getMax
功能的栈,采用了同样的方法。
栈的一个很重要的功能就是用于记录历史操作,并用于回滚。比如Word中的撤销功能,就是记录了指定次数的连续操作,如果需要回滚就弹出栈中的记录进行回滚操作,并把最新的行为推入栈中。利用栈的这一性质可以记录在每一阶段中,每一个栈深度内的最小值。
用一个栈保存正常栈的所有数据元素,用另外一个栈来记录每步操作的”历史” 栈中最小值。当一个数据入栈时,如果这个数据小于或者等于”历史”栈中的顶部值,也就是刷新了当前栈中的最小值记录,就把这个值也压入最小值栈中。根据这个压栈条件,只有不比最小栈栈顶元素大的数据才能入最小栈,也就是这个最小栈中的元素自底向上是非下降的。再来一个新的数据如果不能刷新当前记录,就不能入最小栈,也就是这个最小栈里的这条数据是到目前为止的最小记录,它的前一条数据就是之前的最小记录。
出栈的时候就要考虑当前出栈的这个数据是否是当前的最小记录,如果是的话这个数据会在出栈后消失,则最小记录就要更新了。而更新之后的记录就是最小栈出栈后的top
。
class MinStack { public MinStack() { stackData = new Stack<Integer>(); stackMin = new Stack<Integer>(); } public void push(int x) { stackData.push(x); if (stackMin.empty()) stackMin.push(x); else if (stackMin.peek() >= x) stackMin.push(x); } public void pop() { if (stackMin.empty()) stackData.pop(); if (stackMin.peek() >= stackData.peek()) { stackMin.pop(); stackData.pop(); } else stackData.pop(); } public int top() { return stackData.peek(); } public int getMin() { return stackMin.peek(); } private Stack<Integer> stackData; private Stack<Integer> stackMin;}
2、由两个栈组成的队列
LeetCode对应题目 232. Implement Queue using Stacks
栈的特点是先进后出,而队列的特点是先进先出。使用两个栈可以把顺序反过来实现类似队列的操作。
一个栈用以作为压入栈,另一个栈作为弹出栈。即压入的时候就将元素放在压入栈,而弹出时若栈中为空,就一次性将压入栈中的元素顺次弹出并且压入弹出栈中,若不空就正常弹出。
public class TwoStacksQueue { public TwoStacksQueue() { stackPush = new Stack<Integer>(); stackPop = new Stack<Integer>(); } public void push(int x) { stackPush.push(x); } public int pop() { if (stackPop.empty()) { while (!stackPush.empty()) stackPop.push(stackPush.pop()); } return stackPop.pop(); } public int peek() { if (stackPop.empty()) { while (!stackPush.empty()) stackPop.push(stackPush.pop()); } return stackPop.peek(); } public boolean empty() { return stackPush.empty() && stackPop.empty(); } private Stack<Integer> stackPush; private Stack<Integer> stackPop;}
3、如何仅用递归函数和栈操作逆序一个栈
觉得与栈并无太大关联,难点在于利用递归函数在每次调用时可以产生一个栈帧保存临时变量,此栈是系统栈。
设计递归函数可以学到的经验是,如果要设计一个带返回值的递归函数,把这个递归函数单纯看做完成此功能的函数去调用,思维不要跟着递归函数递归进去,再对递归结束条件进行仔细考虑。
对于无返回值的递归函数,该函数主要改变了传入参数的状态,这时就要跟进去,一层一层思考这个函数还有哪些地方需要完善,最后确定递归结束条件。
public class ReverseStack { public static int getAndRemoveLastElement(Stack<Integer> stack) { int top = stack.pop(); if (stack.empty()) return top; else { int last = getAndRemoveLastElement(stack); stack.push(top); return last; } } public static void reverse(Stack<Integer> stack) { if (stack.empty()) return; int last = getAndRemoveLastElement(stack); reverse(stack); stack.push(last); }}
4、猫狗队列
设计题,留坑
5、用一个栈实现另一个栈的排序
辅助栈用来顺序放置stack
里的元素,当遇到一个比help
栈顶元素大的stack
元素时,用stack
来临时放置比该元素小的help
栈里的元素,类似插入排序。
class SortStack { public static void sortStackByStack(Stack<Integer> stack) { Stack<Integer> help = new Stack<Integer>(); while (!stack.isEmpty()) { int cur = stack.pop(); while (!help.isEmpty() && help.peek() < cur) { stack.push(help.pop()); } help.push(cur); } while (!help.isEmpty()) { stack.push(help.pop()); } }}
6、用栈来求解汉诺塔问题
难题留坑
7、生成窗口最大值数组
class Solution { public int[] maxSlidingWindow(int[] nums, int k) { if (nums == null || k < 1 || nums.length < k) return new int[0]; LinkedList<Integer> qmax = new LinkedList<Integer>(); int[] res = new int[nums.length-k+1]; int index = 0; for (int i = 0; i < nums.length; ++i) { while (!qmax.isEmpty() && nums[qmax.peekLast()] <= nums[i]) { qmax.pollLast(); } qmax.addLast(i); if (qmax.peekFirst() == i-k) { qmax.pollFirst(); } if (i >= k-1) { res[index++] = nums[qmax.peekFirst()]; } } return res; }}
8、构造数组的MaxTree
9、求最大子矩阵的大小
在直方图最大矩形的基础上稍作改变。统计每一行矩阵的高度,再直接放入largestRectangleArea
算法中求出,更新最大值。
class Solution {public: int maximalRectangle(vector<vector<char>>& matrix) { if (matrix.size() == 0) return 0; int h = matrix.size(), maxarea = 0; vector<int> vec(matrix[0].size(), 0); for (int i = 0; i < h; ++i) { for (int j = 0; j < matrix[i].size(); ++j) { vec[j] = matrix[i][j] == '0' ? 0 : vec[j]+1; } maxarea = max(maxarea, largestRectangleArea(vec)); } return maxarea; } int largestRectangleArea(vector<int>& heights) { if (heights.size() == 0) return 0; int len = heights.size(), maxarea = 0; stack<int> stk; for (int i = 0; i < len; ++i) { while (!stk.empty() && heights[i] <= heights[stk.top()]) { int p = stk.top(); stk.pop(); int k = stk.empty() ? -1 : stk.top(); maxarea = max(maxarea, (i-k-1)*heights[p]); } stk.push(i); } while (!stk.empty()) { int p = stk.top(); stk.pop(); int k = stk.empty() ? -1 : stk.top(); maxarea = max(maxarea, (len-k-1)*heights[p]); } return maxarea; }};
10、最大值减去最小值小于或等于num的子数组数量
- 《程序员代码面试指南》第一章 栈和队列
- 《程序员面试代码指南》之栈和队列中的套路
- 【程序员代码面试指南】-栈和队列-最小栈/ 双栈队列/ 栈排序
- 程序员代码面试指南-猫狗队列(c++)
- 代码面试指南学习记录-第一章01
- 代码面试指南学习记录-第一章02
- 左神指南第一章_栈和队列
- 《程序员代码面试指南》第四章 递归和动态规划
- 【程序员代码面试指南 编程笔记】猫狗队列(C++解法)
- [读书笔记]《程序员代码面试指南》
- 【程序员面试宝典】栈和队列相关面试题
- 第一章 1.3背包、队列和栈
- 设计一个有getMin功能的栈 程序员代码面试指南
- 【程序员代码面试指南】python版(第一天)
- 《程序员面试代码指南》之约瑟夫环问题
- 针对左程云《程序员代码面试指南》一类说明
- 《程序员代码面试指南》Python实现(个人读书笔记)
- 程序员面试宝典第一章总结
- GMock 与 GTest
- lua study1
- Android学习《第一行代码》03
- RPG问题的妙解
- python+selenium自动化测试之路Day7之Xpath定位详解
- 《程序员代码面试指南》第一章 栈和队列
- 单选择与全部选择
- 【keras】解决 example 案例中 MNIST 数据集下载不了的问题
- Nginx负载均衡--(3)Nginx负载均衡配置
- 工业相机的应用及基础知识(2)
- Java基础总结
- java内存-未完待续
- 习题6.1
- PAT甲级 1041. Be Unique (20)