栈与队列的常见应用算法及Java实现

一、栈的常见应用算法

1.1 括号匹配

java 复制代码
import java.util.Stack;

public class BracketMatcher {
    public static boolean isValid(String s) {
        Stack<Character> stack = new Stack<>();
        for (char c : s.toCharArray()) {
            if (c == '(' || c == '[' || c == '{') {
                stack.push(c);
            } else {
                if (stack.isEmpty()) return false;
                char top = stack.pop();
                if ((c == ')' && top != '(') || 
                    (c == ']' && top != '[') || 
                    (c == '}' && top != '{')) {
                    return false;
                }
            }
        }
        return stack.isEmpty();
    }

    public static void main(String[] args) {
        System.out.println(isValid("()[]{}")); // true
        System.out.println(isValid("([)]"));   // false
    }
}

1.2 逆波兰表达式求值

java 复制代码
import java.util.Stack;

public class ReversePolishNotation {
    public static int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for (String token : tokens) {
            if (token.equals("+")) {
                stack.push(stack.pop() + stack.pop());
            } else if (token.equals("-")) {
                int b = stack.pop();
                int a = stack.pop();
                stack.push(a - b);
            } else if (token.equals("*")) {
                stack.push(stack.pop() * stack.pop());
            } else if (token.equals("/")) {
                int b = stack.pop();
                int a = stack.pop();
                stack.push(a / b);
            } else {
                stack.push(Integer.parseInt(token));
            }
        }
        return stack.pop();
    }

    public static void main(String[] args) {
        String[] tokens = {"2", "1", "+", "3", "*"};
        System.out.println(evalRPN(tokens)); // 9
    }
}

1.3 深度优先搜索(DFS)

java 复制代码
void dfs(Node start) {
    Deque<Node> stack = new ArrayDeque<>();
    Set<Node> visited = new HashSet<>();
    
    stack.push(start);
    visited.add(start);
    
    while (!stack.isEmpty()) {
        Node current = stack.pop();
        System.out.println(current.value); // 处理当前节点
        
        // 将当前节点的未访问过的邻居压入栈
        for (Node neighbor : current.neighbors) {
            if (!visited.contains(neighbor)) {
                stack.push(neighbor);
                visited.add(neighbor);
            }
        }
    }
}

二、队列的常见应用算法

2.1 滑动窗口最大值(双端队列)

java 复制代码
import java.util.*;

public class SlidingWindowMaximum {
    public int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || k <= 0) return new int[0];
        
        int n = nums.length;
        int[] result = new int[n - k + 1];
        int ri = 0;
        
        Deque<Integer> deque = new ArrayDeque<>();
        for (int i = 0; i < n; i++) {
            // 移除超出窗口范围的元素
            while (!deque.isEmpty() && deque.peek() < i - k + 1) {
                deque.poll();
            }
            
            // 移除所有小于当前元素的元素,保持队列递减
            while (!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) {
                deque.pollLast();
            }
            
            deque.offer(i);
            
            // 记录窗口最大值
            if (i >= k - 1) {
                result[ri++] = nums[deque.peek()];
            }
        }
        
        return result;
    }
    
    public static void main(String[] args) {
        SlidingWindowMaximum solution = new SlidingWindowMaximum();
        int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 3;
        int[] result = solution.maxSlidingWindow(nums, k);
        System.out.println(Arrays.toString(result)); // [3, 3, 5, 5, 6, 7]
    }
}

2.2 寻找第K大元素(优先队列/堆)

java 复制代码
import java.util.PriorityQueue;

public class KthLargestElement {
    public int findKthLargest(int[] nums, int k) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        
        for (int num : nums) {
            minHeap.offer(num);
            if (minHeap.size() > k) {
                minHeap.poll();
            }
        }
        
        return minHeap.peek();
    }
    
    public static void main(String[] args) {
        KthLargestElement solution = new KthLargestElement();
        int[] nums = {3, 2, 1, 5, 6, 4};
        int k = 2;
        System.out.println(solution.findKthLargest(nums, k)); // 5
    }
}

2.3 广度优先搜索(BFS)

java 复制代码
public void bfs(Node start) {
    if (start == null) {
        return;
    }
    
    Queue<Node> queue = new LinkedList<>();
    Set<Node> visited = new HashSet<>();
    
    queue.offer(start);
    visited.add(start);
    
    while (!queue.isEmpty()) {
        Node current = queue.poll();
        System.out.print(current.val + " ");
        
        // 处理当前节点的邻居
        for (Node neighbor : current.neighbors) {
            if (!visited.contains(neighbor)) {
                visited.add(neighbor);
                queue.offer(neighbor);
            }
        }
    }
}
相关推荐
databook3 小时前
使用 SciPy 库进行时间序列分析
python·数据分析·scipy
java资料站3 小时前
十一、评估测试
开发语言·人工智能·python
szial4 小时前
网络爬虫与 CDP 实战(二):浏览器能访问,Python 却被拒绝?拆开登录态与 CSRF
爬虫·python·csrf
shuoshuohaohao4 小时前
MyBatis 小知识点
java·spring·mybatis
海上小飞龙4 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
青少儿编程课堂5 小时前
后缀自动机解析:本质不同子串与最长重复片段统计
c++·python·算法·bfs·信息学竞赛
朝朝辞暮i5 小时前
C++ 第 12 课:局部变量、作用域、变量生命周期
开发语言·c++·算法
怕浪猫5 小时前
LLM 面试必问的 8 个问题,答不上来直接淘汰
人工智能·python·面试
谢亮_vipxieliang5 小时前
泛型擦除、通配符与 PECS 一次讲透
java·面试
八解毒剂5 小时前
【计组】中央处理器CPU
java·开发语言·计算机组成原理