这是跟着LeetCode上的一个学习计划(剑指Offer)来做的,已经鸽了十几天没去做,然后又开始猛刷,但是刷完就过了,没有做总结,所以,闲暇时间开始对做过的题做一个回顾和总结。。。
剑指 Offer 09. 用两个栈实现队列
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
思路
栈是先进后出的,而队列是先进先出的,要让栈实现先进先出,那么两个栈,一个进,一个出,就可以简单实现先进先出的效果。
首先定义两个栈,in 和 out 在这个“队列”中,当元素入队是,push 到 in 中;当元素出队,则首先观察 out 中有没有元素,如果没有,则将 in 中所有的元素都出栈再 push 到 out,这一步就相当于把先进后出变成了先进先出,最后在 out 中push即可。
代码
class CQueue {
Stack<Integer> in, out;
public CQueue() {
in = new Stack<>();
out = new Stack<>();
}
public void appendTail(int value) {
in.push(value);
}
public int deleteHead() {
if (out.isEmpty() && in.isEmpty()) return -1;
if (out.isEmpty()) {
while (!in.isEmpty()) {
out.push(in.pop());
}
}
if (!out.isEmpty()) return out.pop();
return -1;
}
}
剑指 Offer 30. 包含min函数的栈
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
思路
因为是实现栈,这里底层可以采用一个链表的形式来存储。min的方法比较简单,就是保存当前栈状态的一个最小值情况,每一次压栈,如果最小值发生变化,就保存下来上一个状态的最小值,同样维护在链表中即可;同理,如果出栈的是当前的最小值,则需要将出栈后最小值从链表中取出。
代码
class MinStack {
private int min;
private Node head;
class Node {
int val;
Node next;
public Node(int val, Node next) {
this.val = val;
this.next = next;
}
}
public MinStack() {
head = null;
min = Integer.MAX_VALUE;
}
public void push(int x) {
if (x <= min) {
head = new Node(min, head);
min = x;
}
head = new Node(x, head);
}
public void pop() {
if (head.val == min) {
min = head.next.val;
head = head.next.next;
} else {
head = head.next;
}
}
public int top() {
return head.val;
}
public int min() {
return min;
}
}
\