1.括号匹配问题
1.遍历字符串
2.遇到左括号则入栈
3.遇到右括号,若栈空,返回 false,否则取出栈顶元素,若不匹配则返回 false
4.当字符串遍历完且栈为空,返回 true
public static boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
//遇到左括号入栈
char c = s.charAt(i);
if (c == '(' || c == '[' || c == '{') {
stack.push(c);
} else { //遇到右括号则取出栈顶元素观察是否匹配
if (stack.isEmpty()) {
return false;
}
char x = stack.pop();
//System.out.println("c = " + c + " x = " + x);
if (!isMatch(x, c)) {
return false;
}
}
}
if (stack.isEmpty()) {
return true;
}
return false;
}
//检查两个符号是否匹配
public static boolean isMatch(char a, char b) {
if (a == '(' && b == ')') {
return true;
}
if (a == '[' && b == ']') {
return true;
}
if (a == '{' && b == '}') {
return true;
}
return false;
}
2.用队列实现栈
队列A 实现出入栈的主要据点,队列B 作为辅助
入栈:元素进入到A
出栈:A中的元素依次进入到B中,直到A中只剩一个元素,取出该元素。互换AB。
栈顶元素:A中的元素依次进入到B中,直到A中只剩一个元素,得到并取出该元素。互换AB。
栈是否空:A、B中均无元素
import java.util.LinkedList;
import java.util.Queue;
public class $225 {
Queue<Integer> qA = new LinkedList<>();
Queue<Integer> qB = new LinkedList<>();
/** Initialize your data structure here. */
// public MyStack() {
//
// }
/** Push element x onto stack. */
public void push(int x) {
qA.offer(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
if (qA.size() == 0) {
return -1;
}
//A 一直往 B 放元素直到 A 只剩一个元素
while (qA.size() != 1) {
qB.offer(qA.poll());
}
int x = qA.poll();
Queue tmp;
tmp = qA;
qA = qB;
qB = tmp;
return x;
}
/** Get the top element. */
public int top() {
if (qA.size() == 0) {
return -1;
}
//A 一直往 B 放元素直到 A 只剩一个元素
while (qA.size() != 1) {
qB.offer(qA.poll());
}
int x = qA.peek();
qB.offer(qA.poll());
Queue tmp;
tmp = qA;
qA = qB;
qB = tmp;
return x;
}
/** Returns whether the stack is empty. */
public boolean empty() {
if (qA.size() == 0 && qB.size() == 0) {
return true;
}
return false;
}
}
3.用栈实现队列
入队列:将B中所有元素放入A中,再将新元素放入栈A
出队列:将B中所有元素放入A中,再将A中的元素依次放入B中直到A中只剩一个元素,取出该元素
取栈顶元素:将B中所有元素放入A中,再将A中的元素依次放入B中直到A中只剩一个元素,得到该元素
public class $232 {
Stack<Integer> sA = new Stack<>();
Stack<Integer> sB = new Stack<>();
/** Initialize your data structure here. */
// public MyQueue() {
//
// }
/** Push element x to the back of queue. */
public void push(int x) {
if (!sB.isEmpty()) {
sA.push(sB.pop());
}
sA.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if (!sB.isEmpty()) {
sA.push(sB.pop());
}
if (sA.size() == 0) {
return -1;
}
while (sA.size() != 1) {
sB.push(sA.pop());
}
int x = sA.pop();
return x;
}
/** Get the front element. */
public int peek() {
if (!sB.isEmpty()) {
sA.push(sB.pop());
}
if (sA.size() == 0) {
return -1;
}
while (sA.size() != 1) {
sB.push(sA.pop());
}
int x = sA.peek();
return x;
}
/** Returns whether the queue is empty. */
public boolean empty() {
if (sA.size() == 0 && sB.size() == 0) {
return true;
}
return false;
}
}
4.实现一个最小栈
空间换时间,栈A 保存栈中的数据,栈B 保存当前栈帧对应的最小值
入栈:A入栈,若B 非空,入栈顶元素与新元素的最小值,否则入新元素
出栈:AB均出栈
栈顶元素:A的栈顶元素
最小栈:B的栈顶元素
public class $155 {
Stack<Integer> stack = new Stack<>();
Stack<Integer> minStack = new Stack<>();
/** initialize your data structure here. */
// public MinStack() {
//
// }
public void push(int x) {
stack.push(x);
if (!minStack.isEmpty()) {
minStack.push(Math.min(minStack.peek(), x));
} else {
minStack.push(x);
}
}
public void pop() {
stack.pop();
minStack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
5.设计循环队列
利用数组实现循环队列
front:指向队首元素
rear:指向队尾元素的下一位
队空:front = rear
队满:(rear+1) % cap == front
注意front和rear的移动
public class $622 {
int[] queue; //队列
int front; //队首
int rear; //队尾
int capacity;
/** Initialize your data structure here. Set the size of the queue to be k. */
public $622(int k) {
capacity = k+1;
queue = new int[capacity];
front = 0;
rear = 0;
}
/** Insert an element into the circular queue. Return true if the operation is successful. */
public boolean enQueue(int value) {
//考虑队列满
if (isFull()) {
return false;
}
queue[rear] = value;
rear = (rear+1)%capacity;
return true;
}
/** Delete an element from the circular queue. Return true if the operation is successful. */
public boolean deQueue() {
if (isEmpty()) {
return false;
}
front = (front+1)%capacity;
return true;
}
/** Get the front item from the queue. */
public int Front() {
if (isEmpty()) {
return -1;
}
return queue[front];
}
/** Get the last item from the queue. */
public int Rear() {
if (isEmpty()) {
return -1;
}
return queue[(rear+capacity-1)%capacity];
}
/** Checks whether the circular queue is empty or not. */
public boolean isEmpty() {
return front == rear;
}
/** Checks whether the circular queue is full or not. */
public boolean isFull() {
return (rear + 1) % capacity == front;
}
}