1. 用栈实现队列
Leetcode (opens new window)/ 力扣
栈的顺序为后进先出,而队列的顺序为先进先出。使用两个栈实现队列,一个元素需要经过两个栈才能出队列,在经过第一个栈时元素顺序被反转,经过第二个栈时再次被反转,此时就是先进先出顺序。
/**
* 思路:维护两个栈,一个栈负责输入,一个栈负责输出
* push() 直接将数压入输入栈即可
* pop() 首先检查输出栈是否为空,如果为空就就把输入栈
* 的数读出到输出栈中
* peek()
*
*/
class MyQueue {
private Stack<Integer> in;
private Stack<Integer> out;
public MyQueue() {
in = new Stack<>();
out = new Stack<>();
}
public void push(int x) {
in.push(x);
}
public int pop() {
if (out.isEmpty()) {
inToOut();
}
return out.pop();
}
public int peek() {
inToOut();
return out.peek();
}
public boolean empty() {
return in.isEmpty() && out.isEmpty();
}
public void inToOut() {
if (out.isEmpty()) {
while (!in.isEmpty()) {
out.push(in.pop());
}
}
}
}
2. 用队列实现栈
Leetcode (opens new window)/ 力扣
在将一个元素 x 插入队列时,为了维护原来的后进先出顺序,需要让 x 插入队列首部。而队列的默认插入顺序是队列尾部,因此在将 x 插入队列尾部之后,需要让除了 x 之外的所有元素出队列,再入队列。
class MyStack {
Queue<Integer> queue;
public MyStack() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
int size = queue.size();
while (size-- > 1) {
queue.add(queue.poll());
}
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
3. 最小值栈
Leetcode (opens new window)/ 力扣
class MinStack {
// 数据栈
private Stack<Integer> stack;
// 最小值栈,与数据栈对应
private Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int val) {
stack.push(val);
// 如果为空,就不用比较,直接入栈
if (minStack.isEmpty()) {
minStack.push(val);
} else {
// 如果栈顶元素比 val 小,直接入栈
if (minStack.peek() > val) {
minStack.push(val);
// 否则将以前的最小值入栈
} else {
minStack.push(minStack.peek());
}
}
}
public void pop() {
// 两个栈是同步的
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
4. 用栈实现括号匹配
Leetcode (opens new window)/ 力扣
class Solution {
public boolean isValid(String s) {
if (s.length() % 2 == 1) {
return false;
}
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(' || ch == '{' || ch == '[') {
stack.push(ch);
} else {
if (stack.isEmpty()) {
return false;
}
char temp = stack.pop();
boolean b1 = (ch == ')' && temp != '(');
boolean b2 = (ch == '}' && temp != '{');
boolean b3 = (ch == ']' && temp != '[');
if (b1 || b2 || b3) {
return false;
}
}
}
return stack.isEmpty();
}
}
5. 每日温度
Leetcode (opens new window)/ 力扣
(1)直接暴力遍历
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] result = new int[temperatures.length];
for (int i = 0; i < temperatures.length; i++) {
int count = 0;
// 用于计数,如果真的有比今天温度高的就与 count 相加
int flag = 0;
for (int j = i + 1; j < temperatures.length; j++) {
if (temperatures[i] < temperatures[j]) {
count += flag + 1;
break;
}
flag++;
}
result[i] = count;
}
return result;
}
}
(2)单调栈
class Solution {
public int[] dailyTemperatures(int[] temperatures) {
int[] result = new int[temperatures.length];
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < temperatures.length; i++) {
while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
int index = stack.pop();
result[index] = i - index;
}
stack.push(i);
}
return result;
}
}
6. 下一个更大元素 II *
Leetcode (opens new window)/ 力扣
class Solution {
public int[] nextGreaterElements(int[] nums) {
int length = nums.length;
int[] result = new int[length];
Stack<Integer> stack = new Stack<>();
// 把数组初始化为 -1
Arrays.fill(result, -1);
for (int i = 0; i < length * 2; i++) {
int temp = nums[i % length];
while (!stack.isEmpty() && temp > nums[stack.peek()]) {
result[stack.pop()] = temp;
}
if (i < length) {
stack.push(i);
}
}
return result;
}
}