机试注意事项 问题1. 泛型参数不能用基本类型错误Mapint, int、Listchar正确MapInteger, Integer、ListCharacter记忆泛型尖括号里只接受引用类型8 种基本类型要用它们对应的包装类。2. 变量必须先声明类型再使用错误直接need target - nums[i];正确int need target - nums[i];记忆Java 是强类型语言任何变量第一次出现都必须带类型除非用varJDK 10 且能推断时。3. 方法调用缺少括号或拼错大小写常见表现str.toCharArray→ 应该是str.toCharArray()map.containskey(need)→ 应该是map.containsKey(need)大写 Kmap.entryset()→ 应该是map.entrySet()大写 Sentry.getValue→ 应该是entry.getValue()new ArrayList→ 应该是new ArrayList()记忆Java 方法名严格区分大小写遵循驼峰命名。调用方法一定要有括号除非是方法引用但那个场景完全不同。4. 语句末尾遗漏分号错误return new int[]{a, b}、map.put(k, v)后面没加;记忆Java 的每条语句结尾都要有;只有花括号{}后面不加。5. 方法缺少 return 语句错误方法声明了返回类型如int[]但只在循环里有return循环外面没有。正确必须在所有执行路径上都有return或最后抛异常。记忆编译器会检查每条可能执行路径的返回值循环结束后需要兜底的 return 或 throw。6. API 返回值类型搞错错误map.put(key, map.getOrDefault(...).add(str))add()返回boolean不是List直接放进put会类型不匹配。正确先拿到列表再添加或者用computeIfAbsent。记忆链式调用时要清楚每一步返回的是什么类型不要想当然。7. 用数组作为 Map 的键内容比较陷阱错误Mapchar[], ListString原因数组的equals/hashCode比较内存地址内容相同也会当成不同的键。正确用String或List等重写了 equals 和 hashCode 的类型作为键。记忆Map 的键不要用原生数组排序或去重时转为不可变、有内容比较能力的对象如String。8. 构造器调用缺少new或括号错误new ArrayList、new ArrayListString正确new ArrayList()或new ArrayListString()记忆new 类名(参数)是固定格式括号不能省泛型可以部分推断但括号必须写。9.Java 严格区分数组 vs List类型访问元素修改元素数组 (int[],String[]等)arr[i]arr[i] valueList(ArrayList,LinkedList等)list.get(i)10.list.set(i, value)10.所有方法都要有()列表的查询方式混淆了数组的查询方式所有变量都要初始化赋null也可以HashMap的containsKey()方法要有KeyHashset和List就不需要两边都必须是boolean类型笔试要注意的问题1.语法错误缺少分号是否有括号变量混淆使用,数组lenght无括号equals和contains有smap.values没有Set等总结就是名字是否有问题是否缺括号是否缺分号2.逻辑错误手动模拟过程额外数据结构还是原地解决打印关键变量在代码中临时加入System.out.println()输出中间结果帮你快速定位逻辑错误。先拿“暴力分”如果时间紧或想不出最优解先写一个能跑的暴力解法提交。系统会按通过的用例比例给分先保住一部分分数再说。3.测试用例边界值忽略没考虑空数组、单元素、重复值、极小值和极大值等边界,同时想好存在多少种情况不然会漏。要考虑是否会溢出的问题要使用除法或者减法这些变小的运算或者使用long等提升内存大小4.语法代码优化问题比如continue和break5.如何在做不出的情况下拿更高的分数输出几种可能的答案先暴力算法再优化6.简单题目可以直接在网页编写并调试提交难题可以回本地IDE编写调试7.微小的额外时间空间开销也可能会导致超长用例不通过优化1.可以使用数组代替哈希表(前提是不需要使用到哈希表的containsKey()方法)不需要记录value时用Set代替HashMap;来说一说使用数组和set来做哈希法的局限。数组的大小是受限制的而且如果元素很少而哈希值太大会造成内存空间的浪费。set是一个集合里面放的元素只能是一个key而两数之和这道题目不仅要判断y是否存在而且还要记录y的下标位置因为要返回x 和 y的下标。所以set 也不能用。2.不记录累加累减值直接使用偏移量代替3.不需要的历史数据就可以使用滚动变量4.巧用数据结构比如把列表替换成栈或者队列5.使用continue和break来剪枝但是要注意不要存在逻辑错误所以如果不是很确定是否有逻辑问题就不剪枝6.统一使用大于等于或者小于等于不然在某些时候可能忽略了等于的情况7.遇到数组可以看看能否排序如果要求返回的是数组的下标就不能排序了或者其他修改数组的操作了。如果数组是允许排序的那么就可以使用双指针解法来代替哈希表解法但是注意排序的时间复杂度是nlogn不要超过算法本身的长度。所以两数之差之和就Hashmap解决三数四数之和之差就用双指针解决(前提是不要求索引即可以排序。8.可以把代码拷贝到本地然后构造输入就能看到输出了9..关于深浅拷贝方法1.Arrays.copyOf—— 复制前 N 个元素或全部javaint[] newArr Arrays.copyOf(int[] original, int newLength);返回一个新数组内容是原数组的前newLength个元素。如果newLength original.length多余位置填默认值0、null 等。如果newLength original.length则截断。内部其实调用了System.arraycopy。javaint[] src {1,2,3};int[] dest Arrays.copyOf(src, 5); // [1,2,3,0,0]int[] trunc Arrays.copyOf(src, 2); // [1,2]2.Arrays.copyOfRange—— 复制指定区间javaint[] newArr Arrays.copyOfRange(int[] original, int from, int to);返回原数组[from, to)区间的新数组。to可以超过数组长度多出部分填默认值。javaint[] src {1,2,3,4};int[] sub Arrays.copyOfRange(src, 1, 3); // [2,3]int[] over Arrays.copyOfRange(src, 2, 6); // [3,4,0,0]3. 对象数组的clone()方法javaint[] dest src.clone();数组的clone()方法返回一个浅拷贝的新数组。对于基本类型数组它等同于深拷贝值复制。对于对象数组复制的是引用两个数组的元素指向同一个对象。javaint[] src {1,2,3};int[] dest src.clone(); // 独立的基本类型数组⚠️clone()对于二维数组只复制外层数组仍然是浅拷贝内层数组还是共享的注意事项对于基本类型数组int[],char[],double[]等不存在“深浅拷贝”的问题——它们直接复制的是值本身所以拷贝后的数组与原数组完全独立修改互不影响。但对于对象数组String[],Integer[], 自定义类数组等和多维数组答案很明确是标准 API 全部都是浅拷贝。1. 对象数组复制的是引用无论你用的是System.arraycopy、Arrays.copyOf、Arrays.copyOfRange、clone()还是Stream.toArray都只会复制数组本身这一层不会复制数组里每个元素指向的对象。2. 二维数组数组的数组更要注意二维数组本质是外层数组的元素都是内层数组的引用。任何复制都只复制了外层数组内层数组还是共享的。3. 那怎样才是深拷贝必须自己手动遍历并逐个复制元素一维对象数组一层循环需要对每个元素手动clone()或new新对象。二维基本类型数组一层循环需要遍历每一行用Arrays.copyOf或clone复制内层数组。int[][] original {{1,2}, {3,4}};int[][] deepCopy new int[original.length][];for (int i 0; i original.length; i) {deepCopy[i] Arrays.copyOf(original[i], original[i].length);//deepCopy[i] original[i].clone();}二维对象数组则需要两层循环并对每个元素进行对象克隆。10.关于时间复杂度O(n^2)能否通过要看n的大小保守起见n ≤ 1000 放心写 O(n²)n ≤ 5000 谨慎评估n 5000 就找更优解。11.要判断题目是实时系统还是预知系统12.输出题目说明给出的返回值时要看清楚是否一模一样有的故意藏了个点号。如InvalidInvalid electionelection.13.如果要抛弃原列表创建新列表还不如直接claer()14.如果没有符合条件的日志标识则输出 NONE意思是返回空数组、、、15.先看题目的注意事项和测试用例来总结题目的规则然后在注释里面写下完整思路写完思路后要回头看思路是否都完全符合规则如果都符合规则就按照思路编写代码。16.要处理的操作好多啊反而思路并不难17.如果出现空指针的问题在网页编译器那里是不会指出具体是哪个代码问题这时候就可以去本地idea编译看看哪里有问题18.contains操作和sort操作本身分别就要O(n)和O(nlogn)的时间不要忽略了他们的时间。如果是无序并且有重复就用contains方法如果是有序并且有重复就用一个滚动变量就行了。19.很多时候AI给出解法是时间最优解代码也很简洁但是就是不够直观难以理解。所以需要它给出时间的最优解同时也要代码直观20.在写代码之前要分析好有哪几种不匹配的情况如果不在动手之前分析好写出的代码也会有很多问题。做算法题的方法自己思考思路如果代码简单就在注释里面写下思路然后按照思路编写代码如果代码冗长就根据自己的思路要AI给出对应代码最后再要求AI给出它的标准解法看看自己的思路是否还能改进。自己的考点总结1. 无序数组 两数之和 → 哈希表本质是记录元素及其索引代表题目两数之和、两数之差P14406套路用哈希表存储值 → 下标或值 → 频次。遍历时找target - x是否已存在。如果只判断是否存在一对可用Set存值。如果需要返回下标用Map存值到下标的映射。如果要求统计对数用Map存频次边遍历边统计。2. 有序数组 两数之和 → 对撞双指针代表题目两数之和 II - 输入有序数组、两数之和在有序情况下套路数组已排序使用左右双指针left 0,right n - 1计算sum nums[left] nums[right]。若sum target找到答案。若sum target左指针右移增大和。若sum target右指针左移减小和。时间复杂度 O(n)空间 O(1)。这是处理有序输入的首选。3. 三数之和 / 四数之和 → 排序 固定一端 对撞双指针代表题目三数之和、四数之和套路先排序然后固定外层元素如三数之和固定第一个数i将问题降维为“在剩余部分找两数之和等于target - nums[i]”。内层使用双指针在有序区间内搜索。去重关键对每个固定位跳过重复值找到解后也要跳过重复的指针值避免结果重复。三数之和O(n²)四数之和O(n³)固定两个数内层双指针。4. 连续子数组和为 K → 前缀和 哈希表本质是记录前缀和的频率代表题目和为 K 的连续子数组右端点固定为当前最后一个元素的和为 K 的连续子数组(P14391)套路并不是找两个独立的数而是找连续子数组的和等于k。维护前缀和preSum问题转化为找两个前缀和之差等于k即preSum[j] - preSum[i] k。遍历时查询当前前缀和pre时找pre - k在哈希表中的出现次数累加。哈希表初始化{0: 1}表示空前缀和。5.字符 / 元素频次统计 → 哈希数组 / 哈希表本质是记录元素出现的频率代表题目赎金信、字母异位词、P14385套路字符范围小如26个小写字母用int[26]代替哈希表。范围大或不确定用HashMapCharacter, Integer。判断两个字符串是否满足某种频次关系可同时增减计数。6.长连续序列 / 并查集辅助 → 哈希表代表题目最长连续序列、数组中的最长连续序列套路将所有数字放入Set。对每个数若x-1不存在则向后枚举x1, x2, ...计算长度。复杂度 O(n)每个数最多访问两次。7.是否重复出现一个元素→ 哈希Set代表题目快乐数即快速判断一个元素是否出现集合里8.覆盖重复值→ 哈希表代表题目准备生日礼物P14208AI分析的考点总结一、哈希表1. 无序数组 两数之和 / 两数之差 → 哈希表代表题目两数之和、两数之差P14406、存在重复元素 II套路哈希表存储值 → 下标或值 → 频次。遍历时查找target - x是否已在哈希表中。只判断是否存在一对用Set存值。需要返回下标用Map存值到下标的映射。统计对数用Map存频次边遍历边累加。2. 无序数组 连续子数组和 → 前缀和 哈希表代表题目和为 K 的连续子数组、统计盈利目标区间P14391套路问题转化为preSum[j] - preSum[i] k。遍历维护当前前缀和pre查找pre - k在哈希表中的出现次数。哈希表初始化为{0: 1}表示空前缀。若要求以当前位置为右端点查询时直接统计pre - target的频次。3. 字符 / 元素频次统计 → 哈希数组 / 哈希表代表题目赎金信、字母异位词、同构字符串、单词模式套路字符范围小如26个小写字母用int[26]代替哈希表。范围大或不确定用HashMapCharacter, Integer。判断两个字符串是否满足某种频次关系可同时增减计数。4. 长连续序列 / 并查集辅助 → 哈希表代表题目最长连续序列、数组中的最长连续序列套路将所有数字放入Set。对每个数若x-1不存在则向后枚举x1, x2, ...计算长度。复杂度 O(n)每个数最多访问两次。二、双指针1. 有序数组 两数之和 → 对撞双指针代表题目两数之和 II - 输入有序数组、两数之和有序情况套路left 0, right n-1根据sum与target的大小关系移动指针。2. 三数之和 / 四数之和 → 排序 固定外层 内层双指针代表题目三数之和、四数之和、最接近的三数之和套路排序后固定前1或2个元素内层用双指针。去重跳过相同的固定值和指针值。3. 快慢指针环检测、中点代表题目环形链表、环形链表 II、快乐数、寻找重复数套路快指针每次走两步慢指针走一步若相遇则有环环的入口可通过数学关系推导。4. 滑动窗口可变长度满足条件的最小子数组代表题目无重复字符的最长子串、最小覆盖子串、长度最小的子数组套路右指针扩展窗口直到满足条件左指针收缩窗口以优化目标。常用int[]或HashMap维护窗口内字符/频次。5. 双指针处理两个有序数组代表题目合并两个有序数组、两个数组的交集 II套路从后往前合并不用额外空间或两个指针分别遍历。三、前缀和1. 一维前缀和区间和 / 差分数组代表题目区域和检索 - 数组不可变、连续子数组和为 K、航班预订统计套路preSum[i1] preSum[i] nums[i]区间[l,r]和为preSum[r1] - preSum[l]。2. 二维前缀和矩阵区域和代表题目二维区域和检索 - 矩阵不可变、统计全 1 子矩形套路dp[i1][j1] dp[i][j1] dp[i1][j] - dp[i][j] matrix[i][j]。3. 前缀和 哈希表连续子数组和问题见哈希表部分第2点。四、二分查找1. 有序数组查找目标值 → 标准二分代表题目二分查找、搜索插入位置套路while(l r)计算mid判断后收缩区间。2. 查找左右边界 → 二分下界/上界代表题目在排序数组中查找元素的第一个和最后一个位置套路分别实现lowerBound找第一个 target和upperBound找第一个 target。3. 旋转数组中的二分代表题目搜索旋转排序数组、搜索旋转排序数组 II、寻找旋转排序数组中的最小值套路根据mid与left/right的比较确定哪一侧有序再判断 target 在哪一侧。4. 值域二分二分答案代表题目分割数组的最大值、爱吃香蕉的珂珂、H 指数 II套路若问题可转化为“是否存在一种方案使得最大值不超过 X”则对值域进行二分。5. 二维矩阵中的二分代表题目搜索二维矩阵、有序矩阵中第 K 小的元素套路利用矩阵行列有序性二分查找值或对行/列分别二分。五、排序算法1. 自定义比较器排序代表题目根据身高重建队列、最大数、会议室套路使用Arrays.sort配合Comparator按多个字段排序。2. 计数排序 / 桶排序数值范围小时代表题目数组的相对排序、前 K 个高频元素套路已知范围较小用int[]计数然后按频次输出。3. 归并思想的应用逆序对、链表排序代表题目数组中的逆序对、排序链表套路在归并过程中统计或合并。4. 快速选择 (Quickselect) 求 Top K代表题目数组中的第 K 个最大元素、最接近原点的 K 个点套路基于快排分区的选择算法O(n) 平均。5. 堆排序Top K 问题代表题目前 K 个高频元素、查找和最小的 K 对数字套路使用优先队列小顶堆求最大 K大顶堆求最小 K。六、动态规划1. 背包问题01背包、完全背包代表题目分割等和子集01背包、零钱兑换完全背包、组合总和 IV套路定义dp[i][j]或优化为滚动数组递推式根据是否可重复选择物品。2. 线性 DP一维 / 二维代表题目爬楼梯、打家劫舍、不同路径、最小路径和套路状态定义如dp[i]表示以 i 结尾的最优值状态转移依赖前几个状态。3. 区间 DP代表题目最长回文子串、戳气球套路dp[i][j]表示区间[i,j]的最优解遍历区间长度递增。4. 状态机 DP买卖股票最佳时机系列代表题目买卖股票的最佳时机含冷冻期、手续费等套路定义多个状态持有/不持有/冷冻状态转移图清晰。5. 树形 DP代表题目打家劫舍 III、二叉树中的最大路径和套路后序遍历每个节点返回多个状态值。6. 双序列 DP字符串编辑距离等代表题目最长公共子序列、编辑距离、正则表达式匹配套路dp[i][j]表示s1[0..i-1]和s2[0..j-1]的最优解。七、贪心算法1. 区间调度最多不重叠区间、合并区间代表题目无重叠区间、用最少数量的箭引爆气球、合并区间套路按结束时间或开始时间排序依次贪心选择。2. 跳跃游戏系列代表题目跳跃游戏、跳跃游戏 II套路维护当前能到达的最远距离步数最少时用贪心更新下一步的最远范围。3. 分配问题饼干、种花等代表题目分发饼干、种花问题、加油站套路排序后从小到大满足最小需求或用贪心遍历。4. 字典序问题代表题目去除重复字母、拼接最大数套路维护单调栈贪心地保证字典序最小/最大。八、DFS深度优先搜索1. 排列 / 组合 / 子集问题回溯代表题目全排列、子集、组合总和套路递归选择列表剪枝使用boolean[] used标记或索引参数去重。2. 二维网格搜索Flood Fill、岛屿问题代表题目岛屿数量、被围绕的区域、单词搜索套路遍历每个格子DFS 向四个方向探索修改原值或用visited标记。3. 图 / 树的深度遍历前序、中序、后序代表题目路径总和、二叉树的所有路径、N 皇后套路递归或栈模拟传入路径参数回溯时恢复状态。4. 记忆化 DFS自顶向下 DP代表题目不同路径 II、矩阵中的最长递增路径套路DFS 备忘录哈希或数组避免重复计算。九、BFS广度优先搜索1. 最短路径 / 最少步数无权图代表题目打开转盘锁、单词接龙、腐烂的橘子套路使用队列记录步数一层层扩散访问标记防止重复。2. 二叉树层序遍历代表题目二叉树的层序遍历、二叉树的锯齿形层序遍历套路队列每次处理当前层所有节点。3. 拓扑排序BFS / Kahn 算法代表题目课程表、课程表 II套路计算入度将入度为 0 的节点入队依次出队并减少邻居入度。十、栈1. 括号匹配与表达式求值代表题目有效的括号、基本计算器、逆波兰表达式求值套路遇到左括号/操作数入栈右括号/运算符出栈处理。2. 单调栈找下一个更大/更小元素代表题目每日温度、下一个更大元素 I/II、接雨水套路维护一个单调递增或递减的栈当前元素与栈顶比较破坏单调性时弹出。3. 用栈实现队列 / 用队列实现栈代表题目用栈实现队列、用队列实现栈套路两个栈或队列互相倒腾。十一、队列与双端队列1. 滑动窗口最大值 → 单调队列代表题目滑动窗口最大值套路使用双端队列维护窗口内元素的递减队列队首即为最大值。2. BFS 的标准容器见 BFS 部分队列用于逐层扩展。3. 优先队列堆的应用代表题目合并 K 个有序链表、数据流的中位数套路小顶堆存最小值或最大值根据场景选择。十二、树 / 二叉树1. 遍历前序、中序、后序、层序代表题目二叉树的遍历、二叉树的最近公共祖先、验证二叉搜索树套路递归或迭代栈/队列利用 BST 性质或路径记录。2. 二叉树构造代表题目从前序与中序遍历序列构造二叉树、将有序数组转换为二叉搜索树套路根据遍历顺序确定根节点和左右子树范围递归构建。3. 序列化与反序列化代表题目二叉树的序列化与反序列化、验证二叉树的前序序列化套路层序或前序用特殊标记表示 null。4. 二叉搜索树的特性中序有序、搜索、插入、删除代表题目二叉搜索树中的搜索、删除二叉搜索树中的节点套路利用val大小关系决定向左或向右删除时分三种情况无子节点、一个子节点、两个子节点。十三、并查集Union-Find1. 动态连通性 / 合并集合代表题目省份数量、冗余连接、账户合并套路初始化parent[i] i实现find路径压缩和union按秩合并用于判断两元素是否同集合。2. 网格连通分量代表题目岛屿数量也可用 DFS、被围绕的区域套路将二维坐标映射为一维索引初始化并查集合并相邻的连通单元。十四、位运算1. 常见位操作代表题目只出现一次的数字、只出现一次的数字 II/III、汉明距离套路利用异或^消除重复偶数次数字x (-x)获取最低位的 1x (x - 1)消除最低位 1。2. 状态压缩 / 子集枚举代表题目子集 II、最短超级串套路用二进制位表示元素是否被选取遍历0到(1n)-1。3. 位运算模拟加减乘除代表题目两整数之和、二进制加法套路用和^模拟无进位加法和进位循环直到进位为 0。十五、模拟1. 过程模拟按规则一步一步操作代表题目螺旋矩阵、机器人行走、实现 strStr()匹配过程套路明确状态转移规则用循环或递归模拟过程注意边界和方向数组。2. 设计数据结构模拟实际组件代表题目LRU 缓存、LFU 缓存、设计循环队列套路组合使用现有的数据结构如LinkedHashMap、双向链表 哈希表实现所需接口。十六、暴力枚举1. 直接枚举所有可能解代表题目统计特殊四元组、回文子串数量、统计子串中的唯一字符套路当输入规模较小时n ≤ 100~200多层循环枚举所有组合、子数组、子序列验证条件。2. 回溯 / DFS 枚举所有情况见 DFS 部分。十七、二叉树和树1. 二叉树遍历前序、中序、后序 → 递归 / 栈模拟代表题目二叉树的前序遍历、中序遍历、后序遍历、N 叉树的前序/后序遍历套路递归按顺序访问根、左子树、右子树。迭代使用栈模拟递归过程前序先压右再压左中序一直向左走到底再弹出后序可用前序变形根右左 - 反转或标记节点。N 叉树类似递归遍历子节点列表。2. 二叉树层序遍历 → 队列 BFS代表题目二叉树的层序遍历、锯齿形层序遍历、N 叉树的层序遍历、二叉树的右视图套路队列存储每一层节点循环处理当前队列大小次每次弹出节点并加入其左右子节点。锯齿形根据层号奇偶决定加入结果列表的方向。右视图层序遍历时只保留每层最后一个节点。3. 二叉树的最大深度 / 最小深度 → 递归 / BFS代表题目二叉树的最大深度、二叉树的最小深度、平衡二叉树套路最大深度max(left, right) 1递归到底返回 0。最小深度注意叶子节点定义一侧为空时深度由另一侧决定BFS 遇到第一个叶子节点返回深度。平衡判断每个节点计算左右子树高度差绝对值 ≤ 1 且左右子树均平衡。4. 对称二叉树 / 相同树 / 子树判断 → 递归双指针代表题目对称二叉树、相同的树、另一个树的子树、翻转二叉树套路对称递归比较left.left与right.right以及left.right与right.left。相同树同时遍历两棵树比较节点值是否相等结构是否一致。子树判断先找到根节点相同的位置再调用“相同树”判断或序列化后用字符串匹配。翻转交换左右子树递归翻转。5. 路径总和问题 → 递归 / 回溯代表题目路径总和 I、路径总和 II、路径总和 III、二叉树中的最大路径和套路是否存在根到叶子路径和为 target递归减去当前值到叶子判断是否等于 0。输出所有路径回溯时记录当前路径叶子处满足条件则加入结果。任意路径和不一定要经过根递归计算从当前节点向下延伸的最大单边贡献同时更新全局最大值路径可能由左根右构成。路径总和 III任意起终点但只能向下前缀和 哈希表类似连续子数组和为 K。6. 二叉搜索树BST性质 → 中序遍历有序代表题目验证二叉搜索树、二叉搜索树的最小绝对差、二叉搜索树中的众数、二叉搜索树的第 K 小元素套路验证 BST中序遍历检查是否严格递增或递归传递合法范围[min, max]。第 K 小中序遍历计数到 K 时记录。最小绝对差 / 众数中序遍历相邻节点差值比较。BST 搜索利用大小关系决定向左或向右。7. 二叉树的最近公共祖先LCA → 递归查找代表题目二叉树的最近公共祖先、二叉搜索树的最近公共祖先套路普通二叉树递归在左右子树找 p 和 q若左右各找到一个当前节点即为 LCA若只在一边则那一边的结果即为 LCA。二叉搜索树利用值的大小关系若 p、q 都小于当前节点则去左子树都大于则去右子树否则当前节点就是 LCA。8. 构造二叉树 → 递归分治代表题目从前序与中序遍历序列构造二叉树、从中序与后序遍历序列构造二叉树、将有序数组转换为二叉搜索树套路前序中序前序第一个为根在中序中找到根位置分割左右子树区间递归构造。中序后序后序最后一个为根同样在中序中分割。有序数组转平衡 BST每次取中间元素作为根递归构造左右子树。9. 二叉树序列化与反序列化 → 前序 / 层序 特殊标记代表题目二叉树的序列化与反序列化、验证二叉树的前序序列化套路序列化前序遍历或层序用特殊字符如#表示 null节点间用逗号分隔。反序列化利用队列或索引指针按序列化规则重建树。10. N 叉树的相关操作 → 递归遍历 / 层序遍历代表题目N 叉树的最大深度、N 叉树的层序遍历、N 叉树的前序/后序遍历套路递归时遍历children列表深度返回max(children) 1。序列化添加子节点个数或使用特殊符号分隔。11. 树的其他性质与操作代表题目二叉树展开为链表、填充每个节点的下一个右侧节点指针、完全二叉树的节点个数套路展开为链表前序遍历或反向后序遍历后连接成单向链表。填充右侧指针层序遍历或利用上一层 next 指针连接下一层。完全二叉树节点数利用满二叉树性质高度 h 有 2^h-1 节点否则递归统计左右子树并 1。12.树形结构的递归遍历 / 后序遍历聚合归类树 / 多叉树的深度优先遍历DFS后序遍历先计算子节点子目录/文件的大小再汇总到父节点目录代表题目磁盘空间清理你刚整理的那道题文件系统目录大小统计二叉树中计算子树和套路建树根据文件路径构建多叉树或直接用 HashMap 存储父子关系。后序遍历自底向上叶子节点文件直接返回自身的 Size。非叶子节点目录递归计算所有子节点的占用空间之和自身 Size 为 0。缓存结果用MapString, Long记录每个目录/文件的总占用空间避免重复计算。按需输出根据题目要求找出最大项、排序、或输出指定层级。常见变体只统计一级子目录不需要深层递归汇总但要能区分一级和更深层级的节点。多条件排序大小相同按字典序。路径前缀匹配过滤。一句话总结这类题目本质是树的遍历 聚合统计核心是自底向上的后序遍历思路。常用的api:自定义排序排序算法