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);
}
}
}
}