栈的应用

This commit is contained in:
whai 2024-01-08 20:54:53 +08:00
parent 742d0471b2
commit 5bc369a02d
3 changed files with 342 additions and 0 deletions

View File

@ -0,0 +1,46 @@
package cn.whaifree.leetCode.Stack;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
/**
* 括号匹配
*/
public class LeetCode20 {
@Test
public void test() {
System.out.println(new Solution().isValid("()[]{}"));
System.out.println(new Solution().isValid("}"));
}
class Solution {
public boolean isValid(String s) {
Deque<Character> stack = new LinkedList<>();
char[] chars = s.toCharArray();
for (char aChar : chars) {
if (aChar == '{' || aChar == '[' || aChar == '(') {
stack.push(aChar);
}else if (aChar == ']'){
if (stack.isEmpty() || stack.pop() != '[') {
return false;
}
}else if (aChar == '}'){
if (stack.isEmpty() ||stack.pop()!= '{') {
return false;
}
}else if (aChar == ')'){
if (stack.isEmpty() || stack.pop() != '(') {
return false;
}
}
}
return stack.isEmpty();
}
}
}

View File

@ -0,0 +1,174 @@
package cn.whaifree.leetCode.Stack;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
/**
* 225. 用队列实现栈
*
* 请你仅使用两个队列实现一个后入先出LIFO的栈并支持普通栈的全部四种操作pushtoppop empty
*
* 实现 MyStack
*
* void push(int x) 将元素 x 压入栈顶
* int pop() 移除并返回栈顶元素
* int top() 返回栈顶元素
* boolean empty() 如果栈是空的返回 true 否则返回 false
*
* 注意
*
* 你只能使用队列的基本操作 也就是 push to backpeek/pop from frontsize is empty 这些操作
* 你所使用的语言也许不支持队列 你可以使用 list 列表或者 deque双端队列来模拟一个队列 , 只要是标准的队列操作即可
*
* 示例
*
* 输入
* ["MyStack", "push", "push", "top", "pop", "empty"]
* [[], [1], [2], [], [], []]
* 输出
* [null, null, null, 2, 2, false]
*
* 解释
* MyStack myStack = new MyStack();
* myStack.push(1);
* myStack.push(2);
* myStack.top(); // 返回 2
* myStack.pop(); // 返回 2
* myStack.empty(); // 返回 False
*
*/
public class LeetCode225 {
@Test
public void test() {
Deque<Integer> objects = new LinkedList<>();
objects.add(1);
objects.add(2);
objects.push(3);
System.out.println(objects.pop());
// objects.forEach(x -> System.out.println(x));
MyStack1 myStack = new MyStack1();
myStack.push(1);
myStack.push(2);
myStack.push(3);
System.out.println(myStack.top());
System.out.println(myStack.pop());
}
/**
* 每次入栈就加入其中的非空队列
* 出栈就全部移动到另一个队列并获取最后一个元素
*
* 队列用add // add 尾巴进
* 栈用push // push 头进
* pop 头出
*
* - push pop
* - 队列 add pop
*/
class MyStack {
Deque<Integer> queue1;
Deque<Integer> queue2;
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
public void push(int x) {
if (!queue1.isEmpty()) {
queue1.add(x);
} else {
queue2.add(x);
}
}
public int pop() {
if (!queue1.isEmpty()) {
// 将queue全部导入queue2并获取最后一个元素返回
while (queue1.size()!=1) {
queue2.add(queue1.pop());
}
return queue1.pop();
} else {
// 将queue2全部导入queue1并获取最后一个元素返回
while (queue2.size()!=1) {
queue1.add(queue2.pop());
}
return queue2.pop();
}
}
public int top() {
if (!queue1.isEmpty()) {
// 将queue全部导入queue2并获取最后一个元素返回
while (queue1.size()>1) {
queue2.add(queue1.pop());
}
Integer pop = queue1.pop();
queue2.add(pop);
return pop;
} else {
// 将queue2全部导入queue1并获取最后一个元素返回
while (queue2.size()>1) {
queue1.add(queue2.pop());
}
Integer pop = queue2.pop();
queue1.add(pop);
return pop;
}
}
public boolean empty() {
return queue1.isEmpty() && queue2.isEmpty();
}
}
/**
* push 的时候 把其替换到头部
*/
class MyStack1 {
Deque<Integer> queue;
public MyStack1() {
queue = new LinkedList<>();
}
public void push(int x) {
queue.add(x);
int size = queue.size();
while (size != 1) {
queue.add(queue.pop());
size--;
}
}
public int pop() {
return queue.pop();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
}

View File

@ -0,0 +1,122 @@
package cn.whaifree.leetCode.Stack;
import org.junit.Test;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
/**
* 232. 用栈实现队列
*
* 请你仅使用两个栈实现先入先出队列队列应当支持一般队列支持的所有操作pushpoppeekempty
*
* 实现 MyQueue
*
* void push(int x) 将元素 x 推到队列的末尾
* int pop() 从队列的开头移除并返回元素
* int peek() 返回队列开头的元素
* boolean empty() 如果队列为空返回 true 否则返回 false
* 说明
*
* 只能 使用标准的栈操作 也就是只有 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 pushpoppeek empty
* 假设所有操作都是有效的 例如一个空的队列不会调用 pop 或者 peek 操作
*
*
* 进阶
*
* 你能否实现每个操作均摊时间复杂度为 O(1) 的队列换句话说执行 n 个操作的总时间复杂度为 O(n) 即使其中一个操作可能花费较长时间
*/
public class LeetCode232 {
@Test
public void test() {
MyQueue myQueue = new MyQueue();
System.out.println(myQueue.empty());
myQueue.push(1);
myQueue.push(2);
myQueue.push(3);
myQueue.push(4);
System.out.println(myQueue.peek());
System.out.println(myQueue.pop());
System.out.println(myQueue.empty());
}
/**
只能 使用标准的栈操作 也就是只有 push to top, peek/pop from top, size, is empty 操作是合法的
一个空的队列不会调用 pop 或者 peek 操作
* // 进队列全部放到Enter栈
* // 一旦要出栈检查Out栈有没有如果没有将目前Enter栈全部弹到Out栈再弹出第一个
*
*/
class MyQueue {
Deque<Integer> stackEnter;
Deque<Integer> stackOut;
public MyQueue() {
this.stackEnter = new LinkedList<>();
this.stackOut = new LinkedList<>();
}
public void push(int x) {
stackEnter.push(x);
}
public int pop() {
int peek = peek();
stackOut.pop();
return peek;
}
public int peek() {
if (stackOut.isEmpty()) {
while (!stackEnter.isEmpty()) {
stackOut.push(stackEnter.pop());
}
}
// 不会对空操作
return stackOut.peek();
}
public boolean empty() {
return stackEnter.isEmpty() && stackOut.isEmpty();
}
}
/**
* 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();
*/
}