LeetCode 三道高频中等数组算法详解|除自身乘积、矩阵置零、螺旋矩阵
你好我是fengxin_rou这是我的个人主页fengxin_rou的主页❄️欢迎查看我的专栏我的专栏《Java后端学习》、《JAVASE基础》、《JUC并发》、《redis》、《JVM虚拟机》、《MYSQL》、《黑马点评》、《rabbitmq》、《JavaWebAI的talis学习系统》、《苍穹外卖》目录一、前言为什么数组算法是算法入门核心二、238. 除自身以外数组的乘积中等2.1 题目描述2.2 误区分析新手常踩坑2.3 核心解题思路2.4 Java 完整 AC 代码逐行注释2.5 复杂度分析2.6 解题复盘三、73. 矩阵置零中等3.1 题目描述3.2 新手误区3.3 核心解题思路3.4 Java 完整 AC 代码3.5 复杂度分析3.6 进阶优化思路面试加分项四、54. 螺旋矩阵中等4.1 题目描述4.2 解题难点4.3 核心解题思路4.4 Java 完整 AC 代码4.5 复杂度分析4.6 易错点总结五、三道算法题核心思维总结六、刷题优化与复盘建议结语一、前言为什么数组算法是算法入门核心在算法体系中数组是最基础、最朴素的线性结构几乎所有高级算法动态规划、双指针、贪心、单调栈都建立在数组遍历的基础之上。很多同学刷题卡顿的核心原因不是看不懂复杂算法而是基础数组思维不扎实、边界处理不严谨、不会空间优化。LeetCode 中等难度数组题普遍具备以下特点逻辑不难但是细节极多、易错点密集暴力解法能通过部分案例但无法满足时间、空间要求需要思维转换拆分遍历、状态标记、边界收缩、空间复用今天讲解的三道题覆盖了数组算法三大核心经典思想前后缀拆分思想238原地标记、状态存储思想73动态边界模拟、循环遍历思想54三道题吃透可解决 80% 中等数组、矩阵类面试题型。二、238. 除自身以外数组的乘积中等2.1 题目描述给你一个整数数组 nums返回数组 answer其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。限制条件请勿使用除法时间复杂度必须 O(n)32 位整数范围内无需考虑溢出2.2 误区分析新手常踩坑很多新手第一反应求出数组总乘积每个位置除以当前数字即可。但题目明确禁止除法且存在数组含 0的场景除法方案完全不可行。暴力双重循环 O(n²) 会超时无法通过大数据案例。因此必须使用前后缀乘积拆分的优化思路。2.3 核心解题思路任意位置 i 的结果 i 左侧所有数的乘积 × i 右侧所有数的乘积。我们可以将计算拆分为两次单层遍历左遍历前缀乘积从前往后遍历让 ans[i] 存储当前下标左侧所有元素的累积乘积。右遍历后缀乘积从后往前遍历用临时变量记录右侧累积乘积与当前 ans[i] 相乘得到最终结果。该方案全程仅两次线性遍历严格满足 O(n) 时间复杂度且复用结果数组无额外数组开销空间最优。2.4 Java 完整 AC 代码逐行注释class Solution { public int[] productExceptSelf(int[] nums) { int len nums.length; // 空数组直接返回 if(len 0) return new int[0]; int[] ans new int[len]; // 第一位左侧无元素前缀乘积默认为1 ans[0] 1; // 第一次遍历计算所有位置的前缀乘积 for(int i 1; i len ; i){ ans[i] nums[i-1] * ans[i-1]; } // 临时变量存储后缀乘积 int temp 1; // 第二次遍历从后往前累乘右侧后缀乘积 for(int i len -2 ; i 0 ; i--){ temp * nums[i 1]; ans[i] * temp; } return ans; } }2.5 复杂度分析时间复杂度O(n)两次线性遍历无嵌套循环空间复杂度O(1)仅使用常数临时变量结果数组不计入额外空间2.6 解题复盘本题核心思维就是拆分问题、空间换时间、复用数组。很多算法题不能直接求解结果需要把结果拆分为「前缀后缀」「左状态右状态」分两次遍历合并结果这是数组优化最经典的套路可通用大量算法题型。三、73. 矩阵置零中等3.1 题目描述给定一个 m x n 的矩阵如果一个元素为 0则将其所在行和列的所有元素都设为 0。要求使用原地算法尽可能节省空间。3.2 新手误区新手最容易犯的错误遍历过程中直接置零。如果一边遍历一边修改矩阵后续遍历会把「原本正常的 0」和「我们手动置的 0」混淆导致整表全部置 0出现错误结果。因此正确思路必须分为两步先标记、后修改。3.3 核心解题思路创建两个布尔数组分别记录「当前行是否存在 0」「当前列是否存在 0」第一次遍历全矩阵完成所有行列的 0 状态标记第二次遍历全矩阵只要当前行/列被标记为含 0就将当前位置置零该思路逻辑清晰、可读性极强、无边界 bug面试中优先推荐该写法不易翻车。3.4 Java 完整 AC 代码class Solution { public void setZeroes(int[][] matrix) { int m matrix.length; int n matrix[0].length; // 定义行、列标记数组 boolean[] rowHasZero new boolean[m]; boolean[] colHasZero new boolean[n]; // 第一次遍历标记所有需要置零的行和列 for(int i 0; i m; i){ for(int j 0; j n; j){ if( matrix[i][j] 0){ rowHasZero[i] colHasZero[j] true; } } } // 第二次遍历根据标记原地置零 for(int i 0; i m; i){ for(int j 0; j n; j){ if(rowHasZero[i] || colHasZero[j]){ matrix[i][j] 0; } } } } }3.5 复杂度分析时间复杂度O(m*n)两次矩阵遍历空间复杂度O(mn)使用两个标记数组是性价比极高的解法3.6 进阶优化思路面试加分项如果题目要求极致空间优化可以复用矩阵第一行、第一列作为标记位可以将空间复杂度压缩至 O(1)适合高阶面试手撕代码原理和本文思路一致只是将外部数组改为原地标记。四、54. 螺旋矩阵中等4.1 题目描述给你一个 m 行 n 列的矩阵 matrix请按照顺时针螺旋顺序返回矩阵中的所有元素。螺旋遍历顺序从左到右 → 从上到下 → 从右到左 → 从下到上循环往复逐层向内收缩。4.2 解题难点本题无复杂算法难点在于边界控制与循环终止条件。很多同学代码逻辑正确但边界判断出错导致漏遍历、重复遍历、数组越界。4.3 核心解题思路定义四个动态边界左边界 l、右边界 r上边界 t、下边界 b四轮遍历 边界收缩左 → 右遍历完成后上边界下移上 → 下遍历完成后右边界左移右 → 左遍历完成后下边界上移下 → 上遍历完成后左边界右移每一轮遍历结束后判断边界是否交叉交叉则说明遍历完成直接终止循环。4.4 Java 完整 AC 代码import java.util.ArrayList; import java.util.Arrays; import java.util.List; class Solution { public ListInteger spiralOrder(int[][] matrix) { if(matrix.length 0) return new ArrayListInteger(); // 定义上下左右边界 int l 0,r matrix[0].length-1,t 0,b matrix.length-1,x 0; Integer[] ans new Integer[(r1) * (b1)]; while(true){ // 1. 从左往右遍历顶层 for(int i l ; i r; i) ans[x] matrix[t][i]; if(t b) break; // 2. 从上往下遍历右侧 for(int i t ; i b ; i) ans[x] matrix[i][r]; if(--r l) break; // 3. 从右往左遍历底层 for(int i r ; i l ; i-- ) ans[x] matrix[b][i]; if(--b t) break; // 4. 从下往上遍历左侧 for(int i b; i t; i--) ans[x] matrix[i][l]; if(l r) break; } return Arrays.asList(ans); } }4.5 复杂度分析时间复杂度O(m*n)每个元素仅遍历一次空间复杂度O(1)仅边界变量结果集合不计入额外空间4.6 易错点总结边界收缩顺序不能乱必须按遍历顺序对应收缩每一轮遍历结束必须判断边界交叉否则会重复遍历内层数据单行、单列矩阵的特殊场景依靠边界判断自动兼容无需单独特判五、三道算法题核心思维总结这三道中等难度数组题覆盖了面试最核心的三种基础算法思维也是所有进阶算法的前提拆分思维238复杂结果拆分为左右两段分治遍历、合并结果规避暴力解法的缺陷。标记思维73只读遍历做标记、二次遍历做修改隔离数据读取与修改避免数据污染。边界模拟思维54用动态边界代替固定下标适配矩阵逐层遍历场景通用性极强。刷题不要只背代码要吃透通用思维模型遇到同类变式题可以直接套思路这才是算法刷题的真正意义。六、刷题优化与复盘建议1. 数组类题目优先思考能否一次遍历、能否空间复用、能否拆分前后缀优先压缩时间与空间复杂度2. 矩阵模拟类题目核心永远是边界控制代码逻辑简单细节决定是否 AC3. 刷题后务必复盘记录易错点、优化思路、面试口述思路做到手撕无 bug、口述逻辑清晰。结语中等数组题是算法分水岭刷透基础数组与矩阵题能够极大提升代码思维、边界处理能力与面试临场手撕能力。本文三道高频题是校招、实习、面试必刷题库建议大家独立手写两遍吃透思路、摆脱题解依赖真正做到举一反三。