内容来自刘宇波老师玩转算法面试
1、栈的基础应用
20 - 有效的括号

| public static boolean isValid(String s) { |
| Stack<Character> stack = new Stack<>(); |
| |
| char[] chars = s.toCharArray(); |
| for (char c : chars) { |
| if (c == '(' || c == '{' || c == '[') stack.push(c); |
| else { |
| if (stack.isEmpty()) return false; |
| char top = stack.pop(); |
| if (c == ')' && top != '(') return false; |
| if (c == '}' && top != '{') return false; |
| if (c == ']' && top != '[') return false; |
| } |
| } |
| |
| return stack.isEmpty(); |
| } |
更多问题
150 - 逆波兰表达式求值
71 - 简化路径
2、栈和递归的密切关系
| public class TreeNode { |
| public int val; |
| public TreeNode left; |
| public TreeNode right; |
| |
| public TreeNode() { |
| } |
| |
| public TreeNode(int val) { |
| this.val = val; |
| } |
| |
| public TreeNode(int val, TreeNode left, TreeNode right) { |
| this.val = val; |
| this.left = left; |
| this.right = right; |
| } |
| } |
更多问题
341 - 扁平化嵌套列表迭代器
2.1、二叉树的前序遍历
144 - 二叉树的前序遍历
递归实现

| public static List<Integer> preorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| preOrder(root, list); |
| return list; |
| } |
| |
| private static void preOrder(TreeNode root, List<Integer> list) { |
| if (root == null) return; |
| |
| list.add(root.val); |
| preOrder(root.left, list); |
| preOrder(root.right, list); |
| } |
用栈实现

| public class Solution { |
| |
| private static class Command { |
| public String s; |
| public TreeNode node; |
| |
| public Command(String command, TreeNode node) { |
| this.s = command; |
| this.node = node; |
| } |
| } |
| |
| public static List<Integer> preorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| if (root == null) return list; |
| |
| Stack<Command> stack = new Stack<>(); |
| stack.push(new Command("go", root)); |
| |
| while (!stack.isEmpty()) { |
| Command command = stack.pop(); |
| String s = command.s; |
| TreeNode node = command.node; |
| |
| if (s.equals("print")) list.add(node.val); |
| else { |
| if (node.right != null) stack.push(new Command("go", node.right)); |
| if (node.left != null) stack.push(new Command("go", node.left)); |
| stack.push(new Command("print", node)); |
| } |
| } |
| |
| return list; |
| } |
| } |
| public static List<Integer> preorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| Stack<TreeNode> stack = new Stack<>(); |
| if (root != null) stack.push(root); |
| |
| while (!stack.isEmpty()) { |
| TreeNode node = stack.pop(); |
| list.add(node.val); |
| if (node.right != null) stack.push(node.right); |
| if (node.left != null) stack.push(node.left); |
| } |
| return list; |
| } |
2.2、二叉树的中序遍历
94 - 二叉树的中序遍历
递归实现
| public static List<Integer> inorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| inorder(root, list); |
| return list; |
| } |
| |
| private static void inorder(TreeNode node, List<Integer> list) { |
| if (node == null) return; |
| |
| if (node.left != null) inorder(node.left, list); |
| list.add(node.val); |
| if (node.right != null) inorder(node.right, list); |
| } |
用栈实现
| public class Solution { |
| |
| private static class Command { |
| public String s; |
| public TreeNode node; |
| |
| public Command(String s, TreeNode node) { |
| this.s = s; |
| this.node = node; |
| } |
| } |
| |
| public static List<Integer> inorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| if (root == null) return list; |
| |
| Stack<Command> stack = new Stack<>(); |
| stack.push(new Command("go", root)); |
| |
| while (!stack.isEmpty()) { |
| Command command = stack.pop(); |
| String s = command.s; |
| TreeNode node = command.node; |
| |
| if (s.equals("print")) list.add(node.val); |
| else { |
| if (node.right != null) stack.push(new Command("go", node.right)); |
| stack.push(new Command("print", node)); |
| if (node.left != null) stack.push(new Command("go", node.left)); |
| } |
| } |
| |
| return list; |
| } |
| } |
2.3、二叉树的后序遍历
145 - 二叉树的后序遍历
递归实现
| public static List<Integer> postorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| postOrder(root, list); |
| return list; |
| } |
| |
| private static void postOrder(TreeNode node, List<Integer> list) { |
| if (node == null) return; |
| |
| if (node.left != null) postOrder(node.left, list); |
| if (node.right != null) postOrder(node.right, list); |
| list.add(node.val); |
| } |
用栈实现
| public class Solution { |
| |
| private static class Command { |
| public String s; |
| public TreeNode node; |
| |
| public Command(String s, TreeNode node) { |
| this.s = s; |
| this.node = node; |
| } |
| } |
| |
| public static List<Integer> postorderTraversal(TreeNode root) { |
| List<Integer> list = new ArrayList<>(); |
| if (root == null) return list; |
| |
| Stack<Command> stack = new Stack<>(); |
| stack.push(new Command("go", root)); |
| |
| while (!stack.isEmpty()) { |
| Command command = stack.pop(); |
| String s = command.s; |
| TreeNode node = command.node; |
| |
| if (s.equals("print")) list.add(node.val); |
| else { |
| stack.push(new Command("print", node)); |
| if (node.right != null) stack.push(new Command("go", node.right)); |
| if (node.left != null) stack.push(new Command("go", node.left)); |
| } |
| } |
| |
| return list; |
| } |
| } |
3、队列的典型应用

102 - 二叉树的层序遍历
| private static class Pair<A, B> { |
| public final A first; |
| public final B second; |
| |
| public Pair(A key, B value) { |
| this.first = key; |
| this.second = value; |
| } |
| } |
| |
| public static List<List<Integer>> levelOrder1(TreeNode root) { |
| List<List<Integer>> res = new ArrayList<>(); |
| if (root == null) return res; |
| |
| Queue<Pair<TreeNode, Integer>> queue = new LinkedList<>(); |
| queue.add(new Pair<>(root, 0)); |
| |
| while (!queue.isEmpty()) { |
| TreeNode node = queue.peek().first; |
| int level = queue.peek().second; |
| queue.remove(); |
| |
| if (level == res.size()) res.add(new ArrayList<>()); |
| res.get(level).add(node.val); |
| |
| if (node.left != null) queue.add(new Pair<>(node.left, level + 1)); |
| if (node.right != null) queue.add(new Pair<>(node.right, level + 1)); |
| } |
| |
| return res; |
| } |
| |
| public static List<List<Integer>> levelOrder2(TreeNode root) { |
| List<List<Integer>> res = new ArrayList<>(); |
| if (root == null) return res; |
| |
| Queue<TreeNode> queue = new LinkedList<>(); |
| queue.add(root); |
| |
| while (!queue.isEmpty()) { |
| List<Integer> list = new ArrayList<>(); |
| int size = queue.size(); |
| |
| for (int i = 0; i < size; i++) { |
| TreeNode node = queue.remove(); |
| list.add(node.val); |
| if (node.left != null) queue.add(node.left); |
| if (node.right != null) queue.add(node.right); |
| } |
| |
| res.add(list); |
| } |
| |
| return res; |
| } |
更多问题
107 - 二叉树的层序遍历 II
103 - 二叉树的锯齿形层序遍历
199 - 二叉树的右视图
4、BFS 和图的最短路径
279 - 完全平方数
5、优先队列相关的算法问题
347 - 前 K 个高频元素
| private static class Pair implements Comparable<Pair> { |
| public int value; |
| public int freq; |
| |
| public Pair(int value, int freq) { |
| this.value = value; |
| this.freq = freq; |
| } |
| |
| @Override |
| public int compareTo(Pair o) { |
| return this.freq - o.freq; |
| } |
| } |
| |
| public static int[] topKFrequent(int[] nums, int k) { |
| |
| Map<Integer, Integer> map = new HashMap<>(); |
| for (int num : nums) map.put(num, map.getOrDefault(num, 0) + 1); |
| |
| |
| PriorityQueue<Pair> pq = new PriorityQueue<>(); |
| |
| Set<Map.Entry<Integer, Integer>> entries = map.entrySet(); |
| for (Map.Entry<Integer, Integer> entry : entries) { |
| Pair pair = new Pair(entry.getKey(), entry.getValue()); |
| |
| if (pq.size() < k) pq.add(pair); |
| else if (pair.freq > pq.peek().freq) { |
| pq.remove(); |
| pq.add(pair); |
| } |
| } |
| |
| int[] res = new int[k]; |
| for (int i = 0; i < res.length; i++) res[i] = pq.remove().value; |
| return res; |
| } |
更多问题
23 - 合并 K 个升序链表
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步