资讯动态

力扣17题:构造乘积矩阵的优化解法与实现

发布时间:2026/9/7 21:43:53 来源:尧图企业网站定制
1. 题目背景与核心需求今天要拆解的是力扣LeetCode第17题构造乘积矩阵这是一道中等难度的数组操作类题目。这类问题在实际编程面试中出现的频率相当高尤其是考察候选人对于数组遍历和空间复杂度的把控能力。题目要求我们给定一个二维矩阵matrix构造一个新的矩阵answer使得answer[i][j]等于matrix中除matrix[i][j]外所有元素的乘积。听起来简单但有几个关键约束条件需要注意必须在不使用除法运算的情况下完成时间复杂度需要控制在O(mn)级别空间复杂度除输出数组外应为O(1)这道题的核心价值在于训练我们对数组遍历顺序的把控以及如何通过预处理来优化计算过程。在实际工程中类似的思想可以应用在图像处理、数据统计分析等多个领域。2. 解题思路分析与比较2.1 暴力解法及其局限性最直观的想法是对于每个元素遍历整个矩阵计算其他所有元素的乘积。这种方法的时间复杂度高达O((mn)^2)当矩阵尺寸较大时完全不可行。比如对于1000×1000的矩阵这种解法需要进行1万亿次乘法运算。注意即使题目没有明确限制时间复杂度面试时提出这种解法也会被直接否决。2.2 使用除法运算的解法如果允许使用除法我们可以先计算整个矩阵所有元素的乘积total然后对于每个元素answer[i][j] total / matrix[i][j]。这种方法时间复杂度为O(mn)非常高效。但题目明确禁止使用除法这主要是考察候选人能否想出更巧妙的解法。在实际工程中如果元素可能为0这种解法还需要特殊处理因为除以0会导致错误。2.3 最优解前缀积与后缀积这道题的标准解法是使用前缀积和后缀积的思想。具体可以分为以下几个步骤第一次遍历矩阵计算每个元素左侧所有元素的乘积前缀积第二次遍历矩阵计算每个元素右侧所有元素的乘积后缀积将前缀积和后缀积相乘得到最终结果对于二维矩阵我们需要分别在行方向和列方向上进行这种处理。这种解法的时间复杂度为O(mn)空间复杂度除输出数组外为O(1)完全符合题目要求。3. 详细实现步骤3.1 初始化与预处理首先我们需要初始化结果矩阵answer大小与原矩阵相同。然后定义两个临时变量left和right来存储前缀积和后缀积。def product_matrix(matrix): if not matrix: return [] m, n len(matrix), len(matrix[0]) answer [[1] * n for _ in range(m)]3.2 计算行方向的前缀积从左到右遍历每一行计算每个元素左侧所有元素的乘积# 计算行方向的前缀积 for i in range(m): left 1 for j in range(n): answer[i][j] left left * matrix[i][j]3.3 计算行方向的后缀积从右到左遍历每一行计算每个元素右侧所有元素的乘积并与之前的前缀积相乘# 计算行方向的后缀积并相乘 for i in range(m): right 1 for j in range(n-1, -1, -1): answer[i][j] * right right * matrix[i][j]3.4 计算列方向的前缀积从上到下遍历每一列计算每个元素上方所有元素的乘积# 计算列方向的前缀积 for j in range(n): up 1 for i in range(m): answer[i][j] * up up * matrix[i][j]3.5 计算列方向的后缀积从下到上遍历每一列计算每个元素下方所有元素的乘积并与之前的列方向前缀积相乘# 计算列方向的后缀积并相乘 for j in range(n): down 1 for i in range(m-1, -1, -1): answer[i][j] * down down * matrix[i][j] return answer4. 复杂度分析与优化4.1 时间复杂度分析我们进行了四次完整的矩阵遍历行方向从左到右行方向从右到左列方向从上到下列方向从下到上每次遍历的时间复杂度都是O(mn)因此总时间复杂度为O(4mn) O(mn)符合题目要求。4.2 空间复杂度分析除了输出矩阵answer外我们只使用了常数个额外变量left, right, up, down因此空间复杂度为O(1)也符合题目要求。4.3 可能的优化方向虽然这个解法已经相当高效但仍有优化空间可以尝试将行方向和列方向的处理合并减少遍历次数对于稀疏矩阵可以跳过0元素的处理使用位运算替代部分乘法操作如果元素都是2的幂次5. 边界条件与特殊处理5.1 空矩阵处理如果输入矩阵为空应该直接返回空矩阵if not matrix: return []5.2 单元素矩阵处理对于1×1的矩阵根据题意应该返回包含1的矩阵因为其他元素的乘积视为1if m 1 and n 1: return [[1]]5.3 包含0元素的处理虽然题目没有明确说明但实际工程中需要考虑矩阵包含0的情况。我们的解法天然支持0元素不需要特殊处理。6. 测试用例设计为了验证代码的正确性应该设计以下几类测试用例常规矩阵[[1,2,3],[4,5,6]]包含0的矩阵[[1,0,3],[4,5,6]]单行矩阵[[1,2,3,4]]单列矩阵[[1],[2],[3]]大尺寸矩阵性能测试[[i*j for j in range(1000)] for i in range(1000)]7. 常见错误与调试技巧7.1 初始化错误常见错误是直接使用answer [[1]*n]*m来初始化矩阵这会导致所有行引用同一个列表。正确做法是使用列表推导answer [[1] * n for _ in range(m)]7.2 遍历顺序错误在计算后缀积时必须从后向前遍历。如果方向弄反了会导致计算结果错误。7.3 边界条件遗漏容易忘记处理空矩阵或单元素矩阵的情况这在面试中会扣分。7.4 变量命名混淆left/right和up/down变量在行列处理时容易混淆建议使用更有意义的变量名如row_prefix和col_prefix。8. 实际应用场景这种构造乘积矩阵的技术在实际工程中有多种应用图像处理中的滤波器计算统计分析中的协方差矩阵计算推荐系统中的相似度矩阵计算金融工程中的风险因子分析理解这种预处理思想可以帮助我们在面对类似问题时快速找到优化方向。9. 扩展思考9.1 更高维度的推广如果将问题扩展到三维或更高维矩阵同样的前缀积/后缀积思想仍然适用只是需要增加更多的遍历方向。9.2 分布式计算实现对于超大规模矩阵可以考虑将矩阵分块在分布式系统中并行计算各部分的前后缀积。9.3 其他变种问题类似的题目变种包括计算每个元素周围邻居的某种聚合值计算到每个元素某种距离范围内的统计量受限条件下的局部乘积计算掌握这类问题的核心思想可以举一反三解决更多相关问题。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价