leecode更新

This commit is contained in:
dingjiawen 2022-09-13 14:43:06 +08:00
parent bb316cd55c
commit 806e02d386
6 changed files with 635 additions and 0 deletions

View File

@ -0,0 +1,123 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import java.util.*;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 12:06
* @Description:
* TODO 力扣150题 逆波兰表达式求值:
* 根据 逆波兰表示法求表达式的值
* 有效的算符包括+-*/每个运算对象可以是整数也可以是另一个逆波兰表达式
* 注意两个整数之间的除法只保留整数部分
* 可以保证给定的逆波兰表达式总是有效的换句话说表达式总会得出有效数值且不存在除数为 0 的情况
* @Version: 1.0
*/
public class EvalRPN {
@Test
public void test(){
String[] tokens = {"2", "1", "+", "3", "*"};
System.out.println(evalRPN(tokens));
}
@Test
public void test1(){
String[] tokens = {"4","13","5","/","+"};
System.out.println(evalRPN(tokens));
}
@Test
public void test2(){
String[] tokens = {"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
System.out.println(evalRPN(tokens));
}
@Test
public void test3(){
String[] tokens = {"2", "1", "+", "3", "*"};
System.out.println(evalRPN(tokens));
}
/**
* 由于没有括号等操作考虑使用一个stack解决遇上运算符就在往前消两栈计算出的结果再入栈
* 由于保证了给定的逆波兰表达式总是有效的所以不需要额外的判断
* 速度击败55%内存击败47%
* @param tokens
* @return
*/
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if(!token.equals("+")&&!token.equals("-")&&!token.equals("*")&&!token.equals("/")){
stack.push(Integer.valueOf(token));
}else {
int num2=stack.pop();
int num1=stack.pop();
if(token.equals("+")){
stack.push(num1+num2);
}else if(token.equals("-")){
stack.push(num1-num2);
}else if(token.equals("*")){
stack.push(num1*num2);
}else if(token.equals("/")){
stack.push(num1/num2);
}
}
}
return stack.pop();
}
/**
* 官方给的使用数组模拟栈代码
* @param tokens
* @return
*/
public int evalRPN1(String[] tokens) {
int n = tokens.length;
int[] stack = new int[(n + 1) / 2];
int index = -1;
for (int i = 0; i < n; i++) {
String token = tokens[i];
switch (token) {
case "+":
index--;
stack[index] += stack[index + 1];
break;
case "-":
index--;
stack[index] -= stack[index + 1];
break;
case "*":
index--;
stack[index] *= stack[index + 1];
break;
case "/":
index--;
stack[index] /= stack[index + 1];
break;
default:
index++;
stack[index] = Integer.parseInt(token);
}
}
return stack[index];
}
}

View File

@ -0,0 +1,87 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import java.util.Stack;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 11:17
* @Description: TODO 力扣20题 有效的括号:
* 给定一个只包括 '('')''{''}''['']'的字符串 s 判断字符串是否有效
* <p>
* 有效字符串需满足
* 左括号必须用相同类型的右括号闭合
* 左括号必须以正确的顺序闭合
* 每个右括号都有一个对应的相同类型的左括号
* @Version: 1.0
*/
public class IsValid {
@Test
public void test() {
String s = "{([([])])}";
System.out.println(isValid(s));
}
/**
* 速度击败98%内存击败35.56%
*
* @param s
* @return
*/
public boolean isValid(String s) {
if (s.length() % 2 != 0) {
return false;
}
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '{' || c == '(' || c == '[') {
stack.push(c);
}
if (c == ')') {
if (stack.size() == 0 || stack.pop() != '(') {
return false;
}
}
if (c == '}') {
if (stack.size() == 0 || stack.pop() != '{') {
return false;
}
}
if (c == ']') {
if (stack.size() == 0 || stack.pop() != '[') {
return false;
}
}
}
if (!stack.empty()) {
return false;
}
return true;
}
/*
某大佬巧妙思路不过就是效率不高
执行用时47 ms, 在所有 Java 提交中击败了5.62%的用户
内存消耗41.4 MB, 在所有 Java 提交中击败了5.01%的用户
*/
public boolean isValid1(String s) {
while (true) {
int l = s.length();
s = s.replace("()", "");
s = s.replace("{}", "");
s = s.replace("[]", "");
if (s.length() == l) {
return l == 0;
}
}
}
}

View File

@ -0,0 +1,111 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.util.Stack;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 09:17
* @Description:
* TODO 力扣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双端队列来模拟一个栈只要是标准的栈操作即可
*
* @Version: 1.0
*/
public class MyQueue {
public Stack<Integer> stack1;
public Stack<Integer> stack2;
public MyQueue() {
stack1=new Stack<>();
stack2=new Stack<>();
}
/**
* 本人思路:
* stack1维护一个反向的stack,stack2就维护一个正向的stack
* push时只push进stack1,每调用一次pop就将stack1的值push进stack2
* 速度击败100%,内存击败50%
* 代码随想录与本思路类似但是他额peek复用了pop(),即pop()之后再添加回去另外也不需要每次再pop会stack1,具体见MyQueue1
* @param x
*/
public void push(int x) {
stack1.push(x);
}
public int pop() {
//放入stack2
while (!stack1.empty()){
stack2.push(stack1.pop());
}
//获取结果
int result=stack2.pop();
//放回stack1
while (!stack2.empty()){
stack1.push(stack2.pop());
}
//返回结果
return result;
}
public int peek() {
//放入stack2
while (!stack1.empty()){
stack2.push(stack1.pop());
}
//查看结果结果
int result=stack2.peek();
//放回stack1
while (!stack2.empty()){
stack1.push(stack2.pop());
}
return result;
}
public boolean empty() {
return stack1.empty();
}
@Test
public void test(){
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
System.out.println(myQueue.peek());// return 1
System.out.println(myQueue.pop());// return 1, queue is [2]
System.out.println(myQueue.empty());// return false
}
}
/**
* 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();
*/

View File

@ -0,0 +1,99 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import java.util.Stack;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 09:17
* @Description:
* TODO 力扣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双端队列来模拟一个栈只要是标准的栈操作即可
*
* @Version: 1.0
*/
public class MyQueue1 {
public Stack<Integer> stack1;
public Stack<Integer> stack2;
public MyQueue1() {
stack1=new Stack<>();
stack2=new Stack<>();
}
/**
* 官方思路:
* 但是他额peek复用了pop(),即pop()之后再添加回去另外也不需要每次再pop会stack1,具体见MyQueue1
* 由于充分利用了两个stack,内存利用率大大提高
* 速度击败100%内存击败96.07%
* @param x
*/
public void push(int x) {
stack1.push(x);
}
public int pop() {
dumpStack();
//返回结果
return stack2.pop();
}
public int peek() {
dumpStack();
return stack2.peek();
}
public boolean empty() {
return stack1.empty()&& stack2.empty();
}
private void dumpStack(){
if(stack2.empty()){
while (!stack1.empty()){
stack2.push(stack1.pop());
}
}
}
@Test
public void test(){
MyQueue1 myQueue = new MyQueue1();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
System.out.println(myQueue.peek());// return 1
System.out.println(myQueue.pop());// return 1, queue is [2]
System.out.println(myQueue.empty());// return false
}
}
/**
* 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();
*/

View File

@ -0,0 +1,120 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 09:59
* @Description: TODO 力扣225题 用队列实现栈:
* 请你仅使用两个队列实现一个后入先出LIFO的栈并支持普通栈的全部四种操作pushtoppop empty
* 实现 MyStack
* void push(int x) 将元素 x 压入栈顶
* int pop() 移除并返回栈顶元素
* int top() 返回栈顶元素
* boolean empty() 如果栈是空的返回 true 否则返回 false
* <p>
* <p>
* 注意
* 你只能使用队列的基本操作 也就是push to backpeek/pop from frontsize 和is empty这些操作
* 你所使用的语言也许不支持队列你可以使用 list 列表或者 deque双端队列来模拟一个队列, 只要是标准的队列操作即可
* @Version: 1.0
*/
public class MyStack {
public Queue<Integer> queue1;
public Queue<Integer> queue2;
public MyStack() {
queue1 = new ArrayDeque<>();
queue2 = new ArrayDeque<>();
}
/**
* 上述方式是使用两个队列实现栈事实上还可以使用一个队列实现栈,具体参考MyStack1
* 速度击败100%内存击败50%
* @param x
*/
public void push(int x) {
if(queue1.isEmpty()&&queue2.isEmpty()){
queue1.add(x);
return;
}
if(queue1.isEmpty()){
//queue1为空,那么queue2不为空
queue1.add(x);
while (!queue2.isEmpty()){
queue1.add(queue2.poll());
}
}else if(queue2.isEmpty()){
//queue1为空,那么queue2为空
queue2.add(x);
while (!queue1.isEmpty()){
queue2.add(queue1.poll());
}
}
}
public int pop() {
if(!queue1.isEmpty()){
return queue1.poll();
}else {
return queue2.poll();
}
}
public int top() {
if(!queue1.isEmpty()){
return queue1.peek();
}else {
return queue2.peek();
}
}
public boolean empty() {
return queue1.isEmpty()&&queue2.isEmpty();
}
// public void dumpStack(){
// if(queue2.isEmpty()){
// while (!queue1.isEmpty()){
// queue2.add(queue1.poll());
// }
// }
// }
@Test
public void test() {
MyStack obj = new MyStack();
obj.push(1);
obj.push(2);
obj.push(3);
int param_2 = obj.pop();
int param_3 = obj.top();
boolean param_4 = obj.empty();
System.out.println(param_2);
System.out.println(param_3);
System.out.println(param_4);
}
}
/**
* 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();
*/

View File

@ -0,0 +1,95 @@
package com.markilue.leecode.stackAndDeque;
import org.junit.Test;
import java.util.ArrayDeque;
import java.util.Queue;
/**
* @BelongsProject: Leecode
* @BelongsPackage: com.markilue.leecode.stackAndDeque
* @Author: dingjiawen
* @CreateTime: 2022-09-13 09:59
* @Description: TODO 力扣225题 用队列实现栈:
* 请你仅使用两个队列实现一个后入先出LIFO的栈并支持普通栈的全部四种操作pushtoppop empty
* 实现 MyStack
* void push(int x) 将元素 x 压入栈顶
* int pop() 移除并返回栈顶元素
* int top() 返回栈顶元素
* boolean empty() 如果栈是空的返回 true 否则返回 false
* <p>
* <p>
* 注意
* 你只能使用队列的基本操作 也就是push to backpeek/pop from frontsize 和is empty这些操作
* 你所使用的语言也许不支持队列你可以使用 list 列表或者 deque双端队列来模拟一个队列, 只要是标准的队列操作即可
* @Version: 1.0
*/
public class MyStack1 {
public Queue<Integer> queue1;
public MyStack1() {
queue1 = new ArrayDeque<>();
}
/**
* 一个队列实现stack,即先把元素加到队列尾部然后再把头pop出在添加到尾部即可
* 速度击败100%内存击败17%
*
* @param x
*/
public void push(int x) {
int size = queue1.size();
queue1.offer(x);
while (size-- > 0) {
queue1.offer(queue1.poll());
}
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
// public void dumpStack(){
// if(queue2.isEmpty()){
// while (!queue1.isEmpty()){
// queue2.add(queue1.poll());
// }
// }
// }
@Test
public void test() {
MyStack1 obj = new MyStack1();
obj.push(1);
obj.push(2);
obj.push(3);
int param_2 = obj.pop();
int param_3 = obj.top();
boolean param_4 = obj.empty();
System.out.println(param_2);
System.out.println(param_3);
System.out.println(param_4);
}
}
/**
* 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();
*/