栈
大家不用看,直接去Leetcode上刷题
定义
stack 是一种线性数据结构,只能在其一端添加数据和移除数据。习惯来讲,这一端称之为栈顶 ,另一端不能操作数据的称之为栈底 。
栈的实现
java
public interface Stack<E> {
// 向栈的顶端压入元素
// 压入成功,返回true; 否则返回false
boolean push(E value);
// 弹出栈顶元素
// 栈非空弹出栈顶元素,否则返回null
E pop();
// 获取栈顶元素,不弹出
// 栈非空弹出栈顶元素,否则返回null
E peek();
// 判断栈是否为空
boolean isEmpty();
// 判断栈是否满
boolean isFull();
}
基于链表的实现
java
public class LinkedListStack<E> implements Stack<E>, Iterable<E> {
static class Node<E> {
E val;
Node<E> next;
public Node(E val) {
this.val = val;
}
public Node (E val, Node<E> next) {
this.val = val;
this.next = next;
}
}
private int capacity;
private int size;
private Node<E> head = new Node<>(null, null);
public LinkedListStack(int capacity) {
this.capacity = capacity;
}
@Override
public boolean push(E val) {
if (isFull()) {
return false;
}
head.next = new Node(val, head.next);
size++;
return true;
}
@Override
public E pop() {
if (isEmpty()) {
return false;
}
Node<E> first = head.next;
head.next = first.next;
size--;
return first.val;
}
@Override
public E peek() {
if (isEmpty()) {
return false;
}
return head.next.val;
}
@Override
public boolean isEmpty(){
return size == 0;
}
@Override
public boolean isFull() {
return size == capacity;
}
public Iterator<E> iterator {
return new Iterable<E> {
Node<E> p = head.next;
@Override
public boolean hasNext(){
p != null;
}
@Override
public E next() {
E val = p.val;
p = p.next;
return val;
}
}
}
}
基于数组的实现
java
public class ArrayStack<E> implements Stack<E>, Iterable<E> {
private E[] array;
private int top; // 栈顶指针
public ArrayStack(int capacity) {
this.array = (E[]) new Object[capacity];
}
@Override
public boolean push(E val) {
if (isFull()) {
return false;
}
array[top++] = val;
return true;
}
@Override
public E pop() {
if (isEmpty()) {
return false;
}
E value = array[--top];
return value;
}
@Override
public E peek() {
if (isEmpty()) {
return false;
}
return array[top - 1];
}
@Override
public boolean isEmpty() {
return top == 0;
}
@Override
public boolean isFull() {
return top == array.length;
}
public Iterator<E> iterator() {
return new Iterator<E>() {
int p = top;
@Override
public boolean hasNext() {
return p > 0;
}
@Override
public E next() {
E value = array[--top];
return value;
}
}
}
}
应用
力扣20
方法一
java
public class Leetcode20{
public boolean isValid(String s) {
ArrayStack<Character> stack = new ArrayStack<>(s.length());
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
stack.push(')');
} else if (c == '[') {
stack.push(']');
} else if (c == '{') {
stack.push('}');
} else {
if (!stack.isEmpty() && c == stack.peek()) {
stack.pop();
} else {
return false;
}
}
}
return stack.isEmpty();
}
}
方法二
java
public class Leetcode20{
Deque<Character> stack = new LinkedList<Character>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '(') {
stack.push(')');
} else if (c == '[') {
stack.push(']');
} else if (c == '{') {
stack.push('}');
} else {
if (!stack.isEmpty() && c == stack.peek()) {
stack.pop();
} else {
return false;
}
}
}
return stack.isEmpty();
}
}
力扣150题
逆波兰表达式也称之为后缀表达式,即运算符写在后面
-
从左向右计算
-
不必考虑运算符优先级,即不用包含括号
输入:token = ["2", "1", "+", "3", "*"];
输出: 9
即:(2 + 1) * 3 = 9输入:token = ["4", "13", "5", "/", "+"];
输出: 6
即:13 / 5 + 3 = 9
java'
public class Leetcode150{
public int evalRPN(String[] tokens) {
LinkedList<Integer> stack = new LinkedList<>();
for(String t : tokens) {
switch (t) {
case "+" -> {
Integer b = stack.pop();
Integer a = stack.pop();
stack.push(a + b);
}
case "-" -> {
Integer b = stack.pop();
Integer a = stack.pop();
stack.push(a - b);
}
case "*" -> {
Integer b = stack.pop();
Integer a = stack.pop();
stack.push(a * b);
}
case "/" -> {
Integer b = stack.pop();
Integer a = stack.pop();
stack.push(a / b);
}
default -> { // 数字
stack.push(Integer.parseInt(t));
}
}
}
return stack.pop();
}
}
中缀表达式转后缀表达式
java
public class InfixToSuffix {
static int priority(char c) {
switch (c) {
case "*", "/" -> 2;
case "+", "-" -> 1;
case "(" -> 0;
default -> throw new IllegalArgumentException("不合法得运算符," + c);
}
}
public String infixToSuffix(String[] exp) {
LinkedList<Character> stack = new LinkedList<>();
StringBuilder sb = new StringBuilder(exp.length());
for(int i = 0; i < exp.length(); i++) {
char c = exp.charAt(i);
switch (c) {
case "*", "/", "+", "-" -> {
if (stack.isEmpty()) {
stack.push(c);
} else {
if (priority(c) > priority(stack.peek())) {
stack.push(c);
} else {
while (stack.isEmpty() && priority(c) <= priority(stack.pop())) {
sb.append(stack.pop());
}
stack.push(c);
}
}
}
case "(" -> {
stack.push(c);
}
case ")" -> {
while (!stack.isEmpty() && stack.peek() != "(") {
sb.append(stack.pop());
}
stack.pop();
}
default -> {
sb.append(c);
}
}
}
while (!stack.isEmpty()) {
sb.append(stack.pop());
}
}
}
使用队列实现栈--leetcode225
使用了两个队列
java
public class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
queue2.offer(x);
while (!queue1.isEmpty()) {
queue2.offer(queue1.poll());
}
Queue<Integer> temp = queue2;
queue2 = queue1;
queue1 = temp;
}
public int pop() {
return queue1.poll();
}
public int peek() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
使用单个队列
java
public MyStack{
Queue<Integer> queue1;
public MyStack() {
queue1 = new LinkedList<>();
}
public void push(int x) {
int size = queue1.size();
queue1.offer(x);
for(int i = 0; i < size; i++) {
queue1.offer(queue1.poll());
}
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.size() == 0;
}
}