//jdk新语法,不需要写break
public int evalRPN(String[] tokens) {
//定义一个栈数据结构
LinkedList<Integer> stack = new LinkedList<>();
//迭代字符串数组中的每一个元素
for (String s : tokens) {
switch (s) {
//如果当前字符为" + ",则将栈顶两个元素弹出,做和运算后再压入栈中
case "+" -> {
int b = stack.pop();
int a = stack.pop();
stack.push(a + b);
}
//如果当前字符串为" - ",则将栈顶两个元素弹出,做差运算后再压入栈中(注意弹栈顺序:先弹栈的做减数)
case "-" -> {
int b = stack.pop();
int a = stack.pop();
stack.push(a - b);
}
//如果当前字符串为" * ",则将栈顶两个元素弹出,做乘积运算后再压入栈中
case "*" -> {
int b = stack.pop();
int a = stack.pop();
stack.push(a * b);
}
//如果当前字符串为" / ",则将栈顶两个元素弹出,做除法运算后再压入栈中(注意弹栈顺序:先弹栈的做除数)
case "/" -> {
int b = stack.pop();
int a = stack.pop();
stack.push(a / b);
}
//如果当前字符串为非运算符,则转为int类型后,压入栈中
default -> {
stack.push(Integer.parseInt(s));
}
}
}
//最后将栈中最后一个也是唯一一个元素返回,即是后缀表达式运算结果
return stack.pop();
}
java复制代码
//jdk旧语法
LinkedList<Integer> stack = new LinkedList<>();
for (String s : tokens) {
switch (s) {
case "+": {
int b = stack.pop();
int a = stack.pop();
stack.push(a + b);
break;
}
case "-": {
int b = stack.pop();
int a = stack.pop();
stack.push(a - b);
break;
}
case "*": {
int b = stack.pop();
int a = stack.pop();
stack.push(a * b);
break;
}
case "/": {
int b = stack.pop();
int a = stack.pop();
stack.push(a / b);
break;
}
default: {
stack.push(Integer.parseInt(s));
}
}
}
return stack.pop();
}
你 只能 使用标准的栈操作 ------ 也就是只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。
示例 1:
复制代码
输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
提示:
1 <= x <= 9
最多调用 100 次 push、pop、peek 和 empty
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)
进阶:
你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。
给LeetCode题目用的自实现栈,可以定义为静态内部类
java复制代码
class ArrayStack<E> {
private E[] array;
private int top; // 栈顶指针
@SuppressWarnings("all")
public ArrayStack(int capacity) {
this.array = (E[]) new Object[capacity];
}
public boolean push(E value) {
if (isFull()) {
return false;
}
array[top++] = value;
return true;
}
public E pop() {
if (isEmpty()) {
return null;
}
return array[--top];
}
public E peek() {
if (isEmpty()) {
return null;
}
return array[top - 1];
}
public boolean isEmpty() {
return top == 0;
}
public boolean isFull() {
return top == array.length;
}
}
参考解答,注意:题目已说明
调用 push、pop 等方法的次数最多 100
java复制代码
public class E04Leetcode232 {
/*
队列头 队列尾
s1 s2
顶 底 底 顶
abc
push(a)
push(b)
push(c)
pop()
*/
ArrayStack<Integer> s1 = new ArrayStack<>(100);
ArrayStack<Integer> s2 = new ArrayStack<>(100);
public void push(int x) {
s2.push(x);
}
public int pop() {
if (s1.isEmpty()) {
while (!s2.isEmpty()) {
s1.push(s2.pop());
}
}
return s1.pop();
}
public int peek() {
if (s1.isEmpty()) {
while (!s2.isEmpty()) {
s1.push(s2.pop());
}
}
return s1.peek();
}
public boolean empty() {
return s1.isEmpty() && s2.isEmpty();
}
}
提交版代码:
java复制代码
class MyQueue
ArrayStack<Integer> s1 = new ArrayStack<>(100);
ArrayStack<Integer> s2 = new ArrayStack<>(100);
public void push(int x) {
s1.push(x);
}
public int pop() {
if (s2.isEmpty()) {
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
}
return s2.pop();
}
public int peek() {
if (s2.isEmpty()) {
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
}
return s2.peek();
}
public boolean empty() {
return s1.isEmpty() && s2.isEmpty();
}
static class ArrayStack<E>{
private final E[] stack;
private int top;
@SuppressWarnings("ALL")
public ArrayStack(int capacity) {
stack = (E[]) new Object[capacity];
}
public boolean push(E value) {
if (isFull()) {
return false;
}
stack[top++] = value;
return true;
}
public E pop() {
if(isEmpty()){
return null;
}
return stack[--top];
}
public E peek() {
if(isEmpty()){
return null;
}
return stack[top-1];
}
public boolean isEmpty() {
return top == 0;
}
public boolean isFull() {
return top == stack.length;
}
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/
LeetCode官方题解:
java复制代码
class MyQueue {
Deque<Integer> inStack;
Deque<Integer> outStack;
public MyQueue() {
inStack = new ArrayDeque<Integer>();
outStack = new ArrayDeque<Integer>();
}
public void push(int x) {
inStack.push(x);
}
public int pop() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.pop();
}
public int peek() {
if (outStack.isEmpty()) {
in2out();
}
return outStack.peek();
}
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
//将输入栈中的元素弹栈并压入输出栈
private void in2out() {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}
}
作者:LeetCode官方题解
链接:https://leetcode.cn/problems/implement-queue-using-stacks/
来源:LeetCode(LeetCode)
思路
将一个栈当作输入栈,用于压入 push 传入的数据;另一个栈当作输出栈,用于 pop 和 peek 操作。
每次 pop 或 peek 时,若输出栈为空则将输入栈的全部数据依次弹出并压入输出栈,这样输出栈从栈顶往栈底的顺序就是队列从队首往队尾的顺序。
class MyStack {
ArrayQueue5<Integer> queue = new ArrayQueue5<>(100);
private int size = 0;
public void push(int x) {
queue.offer(x);
for(int i =0;i<size;i++){
queue.offer(queue.poll());
}
size++;
}
public int pop() {
size--;
return queue.poll();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
static class ArrayQueue5<E>{
private final E[] array;
int head = 0;
int tail = 0;
@SuppressWarnings("all")
public ArrayQueue5(int capacity) {
/*//抛异常
if ((capacity & capacity - 1) != 0) {
throw new IllegalArgumentException("请传入容量为2的N次方的容量参数");
}*/
//增大容量为大于当前参数的最小2的n次方 13 -> 16 22 -> 32
if ((capacity & capacity - 1) != 0) {
int n = (int) ((Math.log10(capacity) / Math.log10(2)) + 1);//计算大于参数的最小2的n次方的n
capacity = 1 << n; //左移运算符,相当于乘2 , 1 << n相当于 2^n
System.out.println(capacity);
}
array = (E[]) new Object[capacity];
}
public boolean offer(E value) {
if (isFull()) {
return false;
}
//使用位运算,规律:当一个数对2的整数次的数取模时,余数=这个数 &(按位与) 2的整数次-1
// 666 % 8 = 666 & 7
/*
求模运算:
- 如果除数是 2 的 n 次方
- 那么被除数的后 n 位即为余数 (模)
- 求被除数的后 n 位方法: 与 2^n-1 按位 与
*/
array[tail & array.length - 1] = value;
tail++;
return true;
}
public E poll() {
if (isEmpty()) {
return null;
}
E value = array[head & array.length - 1];
head++;
return value;
}
public E peek() {
if (isEmpty()) {
return null;
}
E value = array[head & array.length - 1];
return value;
}
public boolean isEmpty() {
return tail == head;
}
public boolean isFull() {
return (tail - head) == array.length;
}
}
}
/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
官方题解:
java复制代码
class MyStack {
Queue<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<Integer>();
}
/** Push element x onto stack. */
public void push(int x) {
int n = queue.size();
queue.offer(x);
for (int i = 0; i < n; i++) {
queue.offer(queue.poll());
}
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}
/** Get the top element. */
public int top() {
return queue.peek();
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}