# 设计一个有getMin功能的栈

LeetCode.155 最小栈

public class MinStack {

Stack<Integer> elements;
Stack<Integer> min;

MinStack() {
elements = new Stack<Integer>();
min = new Stack<Integer>();
}

public int getMin() {
return min.peek();
}

public void push(int x) {
elements.push(x);
if (min.isEmpty() || getMin() > x) {
min.push(x);
} else {
min.push(getMin());
}
}

public int pop() {
min.pop();
return elements.pop();
}

int top() {
return elements.peek();
}
}

# 由两个栈组成的队列

pop时将栈倒腾到另外一个栈里，然后再另外一个栈pop就可以了。

LeetCode.232 用栈实现队列

public class MyQueue {

Stack<Integer> push;
Stack<Integer> pop;

/**
* Initialize your data structure here.
*/
public MyQueue() {
push = new Stack<Integer>();
pop = new Stack<Integer>();
}

/**
* Push element x to the back of queue.
*/
public void push(int x) {
push.push(x);
}

/**
* Removes the element from in front of queue and returns that element.
*/
public int pop() {
if (pop.isEmpty()) {
while (!push.isEmpty()) {
pop.push(push.pop());
}
}

return pop.pop();
}

/**
* Get the front element.
*/
public int peek() {
if (pop.isEmpty()) {
while (!push.isEmpty()) {
pop.push(push.pop());
}
}

return pop.peek();
}

/**
* Returns whether the queue is empty.
*/
public boolean empty() {
return pop.isEmpty() && push.isEmpty();
}
}

public class MyStack {

List<Integer> first;
List<Integer> second;

/**
* Initialize your data structure here.
*/
public MyStack() {
first = new ArrayList<Integer>();
second = new ArrayList<Integer>();
}

/**
* Push element x onto stack.
*/
public void push(int x) {
}

/**
* Removes the element on top of the stack and returns that element.
*/
public int pop() {
while (!first.isEmpty()) {
first.remove(0);
}

Integer integer = second.get(second.size() - 1);
second.remove(second.size() - 1);

return integer;
}

/**
* Get the top element.
*/
public int top() {
while (!first.isEmpty()) {
first.remove(0);
}

Integer integer = second.get(second.size() - 1);

return integer;
}

/**
* Returns whether the stack is empty.
*/
public boolean empty() {
return first.isEmpty() && second.isEmpty();
}
}

# 用栈解决汉诺塔问题

1. 将A中的n-1块积木通过递归过程移动到C。move(n-1,from A,to C)
2. 将A的第n块积木移动到B，print("number n from A to B")
3. 将C中的n-1块积木通过递归过程移动到B。move(n-1,from C,to B)

1. 函数怎么声明？（递归状态是什么？）
2. 递归终止条件是什么？

1. A to B
2. A to C
3. B to A
4. B to C
5. C to A
6. C to B

# 生成窗口最大值数组

1. 队列中记录的是数组的下标
2. 队列的下标所代表的数组值始终保持单调递减
3. 队列中的下标始终是处于窗口中的下标
4. 队列右侧用来刷新新增的下标。如果新增的值比当前队列最后一位所代表的数组值大，从右侧pop直到小于新增值，同时将新增值入队
5. 队列左侧用来刷新下标过期后的值。如果队列左侧的值下标不再在窗口内，从左侧弹出该下标

Todo 找几个leetcode相关题刷刷

# 求最大子矩阵的大小

## 直方图中的最大矩阵面积

1. 栈中存储下标
2. 栈中存储下标对应的值从左到右（从底到顶）始终保持单调递增
3. 从左到右枚举。
1. 如果height[i]比height[stack.peek()]大，i入栈。
2. 否则，依次弹出栈顶元素，记作j。此时形成矩阵的高即为height[j]，那么左边界在哪？最远左边界肯定是左边第一个小于height[j]的值，也就是当前栈顶元素，那么左边界下标就是stack.peek()+1,（如果栈空，左边界下标为0）。则此时矩阵长为(i-(stack.peek()+1)),代表的值。
3. 直到栈顶元素大于i，此时将i入栈。
4. 遍历完成后，栈不为空，同样，当然栈顶元素记为j，j为右边界；依次弹出栈顶元素，找到左边界，计算矩阵值。直到栈为空。
public int maxInZhifangtu(int[] heights, int len) {
Stack<Integer> stack = new Stack<>();
int ans = 0;
for (int i = 0; i < len; i++) {
while (i < len && (stack.isEmpty() || heights[stack.peek()] < heights[i])) {
stack.push(i);
i++;
}
if (i == len) break;
while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {
int j = stack.pop();// i 为右界下标
int height = heights[j];
int k = stack.isEmpty() ? -1 : stack.peek();//k 为左界下标,实际上所求矩阵为(k,i),也就是[k+1,i-1];实际上，j永远会==i-1
ans = Math.max(ans, height * (i - k - 1));
}
stack.push(i);
}

while (!stack.isEmpty()) {
int i = len;
int j = stack.pop();
int height = heights[j];
int k = stack.isEmpty() ? -1 : stack.peek();
ans = Math.max(ans, height * (i - k - 1));
}

return ans;
}
}

posted @ 2019-01-18 00:18  ACBingo  阅读(...)  评论(...编辑  收藏