栈+队列

LC20

package com.wang.leetcode.Stack;

import java.util.Stack;

//有效的括号
//输入字符串
//输出布尔值,判断字符串是否有效
//利用栈先进后出的特性
class Solution20{
    public boolean isValid(String s){
        Stack<Character>left=new Stack<>();
        for (char c:s.toCharArray()){
            if (c=='('||c=='['||c=='{'){
                left.push(c);
            }
            else {
                if (!left.isEmpty()&&leftOf(c)==left.peek()){
                    left.pop();
                }else return false;
            }
        }
        return left.isEmpty();
    }
    char leftOf(char c){
        if (c==')')return '(';
        if (c=='}')return '{';
        return '[';
    }
}
public class LC20 {
    public static void main(String[] args) {
        Solution20 solution20=new Solution20();
        String s = "(]";
        System.out.println(solution20.isValid(s));
    }
}

LC232

image-20250414192417887

package com.wang.leetcode.StackAndQueue;

import java.util.Stack;

//用栈实现队列
//仅使用两个栈实现先入先出队列
/*
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
 */
class MyQueue{
    private Stack<Integer>s1,s2;
    //s1:用于接收新元素(push操作)
    //s2:用于取出元素(pop/peek操作)
    public MyQueue(){
        s1=new Stack<>();
        s2=new Stack<>();
    }

    // 添加元素到队尾
    public void push(int x){
        s1.push(x);
    }

    //删除队头元素并返回
    public  int pop(){
        peek();//确保 s2 里有元素,如果 s2 为空,peek() 会把 s1 的所有元素倒入 s2,保证 s2 的栈顶就是队列的队头。
        return s2.pop();//移除并返回栈s2的顶部元素
    }

    //返回队列开头的元素
    public int peek(){
        if (s2.isEmpty())
            while (!s1.isEmpty())s2.push(s1.pop());
        return s2.peek();//查看s2的栈顶但不移除
    }

    public boolean empty(){
        return s1.isEmpty()&&s2.isEmpty();
    }
}
public class LC232 {
}

LC155

image-20250414193124078

package com.wang.leetcode.StackAndQueue;

import java.util.Stack;

//最小栈
//设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
//实现 MinStack 类:
//MinStack() 初始化堆栈对象。
//void push(int val) 将元素val推入堆栈。
//void pop() 删除堆栈顶部的元素。
//int top() 获取堆栈顶部的元素。
//int getMin() 获取堆栈中的最小元素。
//每个元素入栈时,还要记下来当前栈中的最小值。比方说,可以用一个额外的栈 minStk 来记录栈中每个元素入栈时的栈中的最小元素是多少,这样每次删除元素时就能快速得到剩余栈中的最小元素了。
class MinStack1{
    // 记录栈中的所有元素
    Stack<Integer> stk = new Stack<>();
    // 阶段性记录栈中的最小元素
    Stack<Integer> minStk = new Stack<>();

    public void push(int val){
        stk.push(val);
        // 维护 minStk 栈顶为全栈最小元素
        if (minStk.isEmpty()||val<=minStk.peek()){
            minStk.push(val);
        }else minStk.push(minStk.peek());
    }

    public void pop(){
        stk.pop();
        minStk.pop();
    }

    public int top(){
        return stk.peek();
    }

    public int getMin(){
        return minStk.peek();
    }
}
public class LC155 {
}

LC239

package com.wang.leetcode.StackAndQueue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

//滑动窗口最大值
//给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
//返回 滑动窗口中的最大值 (数组的形式)
//使用一个队列充当不断滑动的窗口
class Solution239{
    // 单调队列的实现
    class MonotonicQueue{
        LinkedList<Integer> q = new LinkedList<>();
        public void push(int n){
            // 将小于 n 的元素全部删除
            while (!q.isEmpty()&&q.getLast()<n){//保持队列单调递减
                q.pollLast();//移除掉尾部的元素(即比n小的元素,因为题目要的是最大的,所以这些元素不可能再用到了)
            }
            q.addLast(n);//删完比n小的元素之后把n加入尾部
        }
        public int max(){
            return q.getFirst();//获取头部元素的值,不移除
        }

        public void pop(int n){//移除队头元素(如果等于 n)
            //当某个元素(通常是滑动窗口左边界)离开窗口时,检查它是否是当前队列的最大值(即队头元素)。
            //如果是,则移除它(因为它已经不在窗口内)。
            if (n==q.getFirst()){//只需要担心最大值
                q.pollFirst();//移除头部元素
            }
        }
    }
    public int[] maxSlidingWindow(int[] nums, int k){
        List<Integer>res=new ArrayList<>();
        MonotonicQueue window = new MonotonicQueue();
        for (int i = 0; i < nums.length; i++) {
            if (i<k-1){ // 先填满窗口的前 k - 1
                window.push(nums[i]);
            }else {
                window.push(nums[i]);
                res.add(window.max());
                window.pop(nums[i-k+1]);//从i=2的情况考虑
            }
        }
        int[]arr=new int[res.size()];
        for (int i = 0; i < res.size(); i++) {
            arr[i]= res.get(i);
        }
        return arr;
    }
}

public class LC239 {
    public static void main(String[] args) {
        Solution239 solution239=new Solution239();
        int[]nums={1,3,-1,-3,5,3,6,7};
        int k=3;
        System.out.println(Arrays.toString(solution239.maxSlidingWindow(nums,k)));
    }
}

LC394

package com.wang.leetcode.StackAndQueue;

import java.util.ArrayDeque;
import java.util.Deque;

//字符串解码
//给定一个经过编码的字符串,返回它解码后的字符串
class Solution394{
    public String decodeString(String s) {
        Deque<Integer> countStack = new ArrayDeque<>(); // 存储数字
        Deque<String> stringStack = new ArrayDeque<>(); // 存储字符串
        String currentString = ""; // 当前解码字符串
        int k = 0; // 当前的倍数

        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) {
                k = k * 10 + (c - '0');
            } else if (c == '[') {
                // 遇到 '[',将当前的字符串和数字推入各自的栈
                countStack.push(k);
                stringStack.push(currentString);
                currentString = ""; // 重置当前字符串
                k = 0; // 重置倍数
            } else if (c == ']') {
                // 遇到 ']',解码
                StringBuilder temp = new StringBuilder(stringStack.pop());
                int repeatTimes = countStack.pop();
                for (int i = 0; i < repeatTimes; i++) {
                    temp.append(currentString); // 重复当前字符串
                }
                currentString = temp.toString(); // 更新当前字符串
            } else {
                // 如果是字母,直接加到当前字符串
                currentString += c;
            }
        }
        return currentString;
    }
}
public class LC394 {
    public static void main(String[] args) {
        Solution394 solution394= new Solution394();
        String s = "3[a2[c]]";
        System.out.println(solution394.decodeString(s));
    }
}

这个好难。。。

posted on 2025-04-19 19:40  红星star  阅读(14)  评论(0)    收藏  举报