赞
踩
目录
① 先进先入。不是所有进完才可以出,入的同时也可以出。
②用数组实现栈:入栈和出栈的时间复杂度是O(1)
③用单链表实现栈:
头插法: 入栈和出栈 O(1)
尾插法:入栈和出栈 O(n)
所以用单链表实现栈时一定要头入头出。
④方法 push、peek、pop、size、empty
① 队尾进,队头出。底层是个双向链表。
②Queue是个接口,在实例化时必须实例化LinkedList的对象。
Queue<Integer> q = new LinkedList<>();
③用单链表实现队列 ok
④ 用数组实现队列 。必须使用循环数组。后面3.6有代码实现逻辑。
④方法 offer、poll、peek、size、isEmpty
核心:入的时候同时可以出
中缀转后缀:按照自己的理解,从左往右加括号,先乘除后加减。再逐步将运算符移到括号后,移
掉所有的(),就是rug
计算中缀表达式的值:遇见数字入栈,遇到运算符就从栈出两个元素。先出的放在运算符的后面,后出栈的放在运算符前面。将计算结果再入栈。
实现代码:
- class Solution {
- public boolean isValid(String s) {
- Stack<Character> stack = new Stack<>();
- for(int i = 0 ;i<s.length();i++){
- char ch = s.charAt(i);
- // 遇见左括号就入栈,注意是单引号
- if(ch == '[' || ch == '{' || ch == '('){
- stack.push(ch);
- }else{
- // 否则,就与栈顶元素进行比较
- // 如果栈是空的,并且遇见的是右括号,直接返回false
- // 判断栈空 不能使用stack==null
- if(stack.isEmpty()){
- return false;
- }else{
- char peek = stack.pop();
- if( (peek == '[' && ch == ']') || (peek == '{' && ch == '}') || (peek == '(' && ch ==')')){
- continue;
- }else{
- return false;
- }
- }
- }
- }
- if(stack.isEmpty()){
- return true;
- }else{
- return false;
- }
- }
- }
OJ链接:150. 逆波兰表达式求值 - 力扣(LeetCode)
实现代码:
- class Solution {
-
- public int evalRPN(String[] tokens) {
- Stack<Integer> stack = new Stack<>();
- HashSet<String> set = new HashSet<>();
- set.add("+");
- set.add("-");
- set.add("*");
- set.add("/");
- for(String str:tokens){
- // 如果遇见的是不是运算符,是数字,就入栈
- if(!set.contains(str)){
- stack.push(Integer.parseInt(str));
- }else{
- // 遇见运算符,就弹出两个数字
- int back = stack.pop();
- int front = stack.pop();
- HashMap<String,Integer> hashMap = new HashMap<>();
- hashMap.put("+",front+back);
- hashMap.put("-",front-back);
- hashMap.put("*",front*back);
- // 注意:back有可能为 0
- if(back != 0){
- hashMap.put("/",front/back);
- }
- //计算结果,将结果入栈
- int result = hashMap.get(str);
- stack.push(result);
- }
- }
- return stack.peek();
- }
- }
OJ链接:栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)
解题思路:
要点1:定义一个pos,记录popA数组中元素的位置。
要点2:遍历pushA,依次将pushA中的元素入栈,判断栈顶元素和popA中的元素是否相同,相同就出栈,并观察popA中的下一个元素是否和新栈顶元素相等。如果不相等,入栈pushA的下一个元素
实现代码:
- import java.util.*;
- import java.util.ArrayList;
-
- public class Solution {
- public boolean IsPopOrder(int [] pushA,int [] popA) {
- Stack<Integer> stack1 = new Stack();
- int pos = 0;
- for(int i=0;i<pushA.length;i++){
- stack1.push(pushA[i]);
- while(!stack1.isEmpty() && stack1.peek() == popA[pos]){
- stack1.pop();
- pos++;
- }
- }
- if(stack1.empty()){
- return true;
- }
- return false;
- }
- }
OJ链接:622. 设计循环队列 - 力扣(LeetCode)
解题思路:
要点1:为了区分队列空和满,约定:
rear指向数组最后一个元素的下一个位置,下一次添加数据,可以直接往rear位置上放
front == rear 队列空
rear的下一个元素是front,队列满了。(rear+1)%elem.length
要点2:返回队列顶部元素,返回front所在位置元素,front向前移。为了保证front可以从3移到1,front=(front+1)%elem.length
要点3:返回队列最后一个元素。如果rear=0,返回elem[elem.length-1].如果rear不为0,就返回elem[rear-1]
实现代码:
- class MyCircularQueue {
-
- private int[] elem;
- private int front;
- private int rear;
-
- public MyCircularQueue(int k) {
- elem = new int[k+1];
- }
-
- public boolean enQueue(int value) {
- if(isFull()){
- return false;
- }
- if(isEmpty()){
- elem[0] = value;
- front = 0;
- rear = 1;
- return true;
- }
- elem[rear] = value;
- rear = (rear+1) % elem.length;
- return true;
- }
-
- public boolean deQueue() {
- if(isEmpty()){
- return false;
- }
- front = (front+1) % elem.length;
- return true;
- }
-
- public int Front() {
- if(isEmpty()){
- return -1;
- }
- return elem[front];
-
- }
-
- public int Rear() {
- if(isEmpty()){
- return -1;
- }
- if(rear == 0){
- return elem[elem.length-1];
- }
- return elem[rear-1];
-
- }
-
- public boolean isEmpty() {
- return rear == front;
-
- }
-
- public boolean isFull() {
- if((rear+1)%elem.length == front){
- return true;
- }
- return false;
-
- }
- }
OJ链接:225. 用队列实现栈 - 力扣(LeetCode)
解题思路:
要点1:有两个队列
要点2:第一次放push数据时,默认放到队列1中
要点3:添加元素时,添加到不为空的队列中,这样才能保证顺序
要点4:出栈—》获得栈顶元素—》栈后入先出—》弹出最后一个入栈的元素
因此,需要找出最后一个入队列的元素。将队列的前n-1个元素,放到另外一个队列中,剩下的就是最后一个入队列的元素
实现代码:
- class MyStack {
-
- private Queue<Integer> qu1;
- private Queue<Integer> qu2;
-
- public MyStack() {
- qu1 = new LinkedList<>();
- qu2 = new LinkedList<>();
- }
-
- public void push(int x) {
- // 如果队列2是空的,就往队列1里面放。原因:只有放在不为空的队列中顺序才不会乱
- if(qu2.isEmpty()){
- qu1.offer(x);
- }else{
- qu2.offer(x);
- }
-
- }
-
- public int pop() {
- if(empty()){
- return -1;
- }
- if(qu1.isEmpty()){
- // 队列2不为空,队列先进先出,将队列前size-1个元素放到队列1中,剩下的最后一个元素就是最后入队列的,也就是栈的第一个元素,将其返回
- int size = qu2.size();
- while(size > 1){
- qu1.offer(qu2.poll());
- size--;
- }
- int result = qu2.poll();
- return result;
- }
- if(qu2.isEmpty()){
- int size = qu1.size();
- while(size > 1){
- qu2.offer(qu1.poll());
- size--;
- }
- int result = qu1.poll();
- return result;
- }
- return -1;
- }
- public int top() {
- if(empty()){
- return -1;
- }
- if(qu1.isEmpty()){
- int size = qu2.size();
- while(size > 1){
- qu1.offer(qu2.poll());
- size--;
- }
- int result = qu2.poll();
- qu1.offer(result);
- return result;
- }
- if(qu2.isEmpty()){
- int size = qu1.size();
- while(size > 1){
- qu2.offer(qu1.poll());
- size--;
- }
- int result = qu1.poll();
- qu2.offer(result);
- return result;
- }
- return -1;
-
- }
-
- public boolean empty() {
- return qu1.isEmpty()&&qu2.isEmpty();
- }
- }
OJ链接:232. 用栈实现队列 - 力扣(LeetCode)
解题思路:
要点1:有两个栈。存数据都存到栈1中,取数据都从栈2中取。
要点2:取数据时,如果栈2是空的,就把栈1中的元素全放到栈2中。再从栈2中取。
实现代码:
- class MyQueue {
- private Stack<Integer> stack1;
- private Stack<Integer> stack2;
- public MyQueue() {
- stack1 = new Stack();
- stack2 = new Stack();
- }
-
- public void push(int x) {
- stack1.push(x);
- }
-
- public int pop() {
- if(empty()){
- return -1;
- }
- if(stack2.empty()){
- while(!stack1.empty()){
- stack2.push(stack1.pop());
- }
- }
- return stack2.pop();
- }
-
- public int peek() {
- if(empty()){
- return -1;
- }
- if(stack2.empty()){
- while(!stack1.empty()){
- stack2.push(stack1.pop());
- }
- }
- return stack2.peek();
-
- }
-
- public boolean empty() {
- return stack1.empty()&&stack2.empty();
-
- }
- }
解题思路:
要点1:创建两个栈。一个栈存放所有的元素,另外一个栈存放栈中最小的元素
要点2:第一次push数据,数据存放在两个栈中
要点3:之后存放数据,该数据小于等于最小栈的栈顶元素,才能存放到最小栈和stack中。否则,就只能存放到stack中
实现代码:
- class MinStack {
- public Stack<Integer> stack;
- public Stack<Integer> minStack;
-
- public MinStack() {
- stack = new Stack();
- minStack = new Stack();
- }
-
- public void push(int val) {
- // 如果第一次放元素,往stack和minStack里都放
- if(stack.empty() && minStack.empty()){
- stack.push(val);
- minStack.push(val);
- return;
- }
- // 如果存放的数据比minStack元素小,该元素同时放到两个栈中
- if(val <= minStack.peek()){
- stack.push(val);
- minStack.push(val);
- return;
- }else{
- // 否则,就只往stack中放
- stack.push(val);
- return;
- }
- }
-
- public void pop() {
- int peek = stack.pop();
- if(peek == minStack.peek()){
- minStack.pop();
- }
- }
-
- public int top() {
- if(stack.empty()){
- return -1;
- }
- return stack.peek();
-
- }
-
- public int getMin() {
- if(minStack.empty()){
- return -1;
- }
- return minStack.peek();
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。