LeetCode 1878题解:斜向前缀和优化菱形和计算

发布时间:2026/11/3 5:56:56
LeetCode 1878题解:斜向前缀和优化菱形和计算 1. 问题背景与核心概念解析这道LeetCode 1878题要求我们在一个m×n的整数矩阵中找出所有可能的菱形和中的前三大值。这里的菱形特指正方形旋转45度后的图形其四个角必须位于矩阵网格点上。举个例子在一个3×3矩阵中中心点可以构成边长为1的菱形而在5×5矩阵中中心点可以构成边长为1和2的菱形。菱形和的计算是这个问题的核心难点。不同于常规的矩形区域求和菱形边界上的元素分布呈现对角线特征。对于一个边长为k的菱形其边界元素位于四条对角线上从中心点向上/下/左/右延伸k步的对角线每条边包含2k-1个元素中心点被四个边共享2. 暴力解法与复杂度分析最直观的解法是暴力枚举所有可能的菱形位置和大小然后计算每个菱形的边界和。具体步骤遍历矩阵中每个点作为菱形中心对于每个中心点枚举可能的菱形边长k对每个k值收集菱形四条边上的元素并求和维护一个大小为3的最大堆记录前三大菱形和这种方法的时间复杂度很高。假设矩阵尺寸为n×n中心点选择O(n²)每个中心可能的k值O(n)每个菱形的边界元素收集O(n) 总复杂度达到O(n⁴)对于n100的情况如题目上限会有1亿次操作显然无法通过测试用例。3. 斜向前缀和优化策略斜向前缀和是解决此类对角线求和问题的利器。我们需要构建两种斜线方向的前缀和数组3.1 斜线方向定义主对角线方向左上到右下同一斜线上i-j为常数副对角线方向右上到左下同一斜线上ij为常数3.2 前缀和数组构建对于每个方向我们构建一个二维前缀和数组# 主对角线方向前缀和 diag1 [[0]*(n1) for _ in range(m1)] for i in range(1, m1): for j in range(1, n1): diag1[i][j] diag1[i-1][j-1] grid[i-1][j-1] # 副对角线方向前缀和 diag2 [[0]*(n1) for _ in range(m1)] for i in range(1, m1): for j in range(n-1, -1, -1): diag2[i][j] diag2[i-1][j1] grid[i-1][j]3.3 菱形边界求和优化利用前缀和数组我们可以在O(1)时间内获取任意斜线段的区间和。对于菱形的一条边可以分解为两段斜线例如右上边从顶点向右下的斜线段 从顶点向左下的斜线段具体计算公式def get_diagonal_sum(diag, i1, j1, i2, j2): # 确保i1i2根据方向调整参数 return diag[i2][j2] - diag[i1-1][j1-1] # 示例计算边长为k的菱形右上边和 # 假设中心在(i,j) right_top get_diagonal_sum(diag1, i-k, j, i, jk) \ get_diagonal_sum(diag2, i, jk, ik, j)4. 完整算法实现结合上述优化我们可以将算法复杂度降低到O(n³)。以下是Python实现的关键部分def getBiggestThree(grid): m, n len(grid), len(grid[0]) res set() # 构建两种斜向前缀和 diag1 [[0]*(n2) for _ in range(m2)] diag2 [[0]*(n2) for _ in range(m2)] for i in range(1, m1): for j in range(1, n1): diag1[i][j] diag1[i-1][j-1] grid[i-1][j-1] for i in range(1, m1): for j in range(n, 0, -1): diag2[i][j] diag2[i-1][j1] grid[i-1][j-1] # 枚举所有可能的菱形 for i in range(m): for j in range(n): res.add(grid[i][j]) # 边长为0的情况 max_k min(i, j, m-1-i, n-1-j) for k in range(1, max_k1): # 计算四条边的和 top diag1[i-k1][j1] - diag1[i][j-k] right diag2[i1][jk1] - diag2[i-k][j] bottom diag1[ik][j1] - diag1[i][j-k] left diag2[i1][j-k1] - diag2[ik][j] total top right bottom left - \ (grid[i-k][j] grid[i][jk] grid[ik][j] grid[i][j-k]) res.add(total) # 返回前三大 res sorted(res, reverseTrue) return res[:3] if len(res) 3 else res5. 边界条件与优化技巧在实际编码中有几个关键点需要注意边界处理前缀和数组通常比原矩阵多一圈避免越界访问。我们使用(m2)×(n2)的数组从(1,1)开始存储有效数据。去重处理使用集合来存储所有可能的菱形和自动处理重复值。k值范围对于中心点(i,j)最大可能的k值为min(i,j,m-1-i,n-1-j)确保菱形不超出矩阵范围。顶点去重四条边的和会重复计算四个顶点的值需要在总和时减去。结果处理题目要求返回前三大值当不足三个时返回所有存在的值。6. 复杂度分析与对比优化前后的复杂度对比暴力法O(n⁴)时间O(1)空间斜向前缀和法O(n³)时间O(n²)空间对于n100的情况暴力法约1亿次操作不可行优化法约100万次操作可行空间方面我们使用了两个额外的n×n数组存储前缀和空间复杂度为O(n²)在合理范围内。7. 实际编码中的常见错误在实现这个算法时容易犯的几个错误前缀和索引混淆原矩阵从0开始计数而前缀和数组通常从1开始容易在索引转换时出错。建议在纸上画出对应关系。菱形边计算遗漏容易漏掉边长为0的情况即单个点或者忘记减去重复计算的顶点值。k值范围错误最大k值计算错误会导致数组越界。正确的计算方式是取四个方向可用空间的最小值。结果去重与排序忘记使用集合去重或者在返回结果时没有正确处理不足三个值的情况。前缀和初始化没有正确初始化前缀和数组的边界值导致后续计算错误。8. 测试用例设计为了验证代码的正确性应该设计以下几类测试用例最小矩阵测试grid [[1]] # 预期输出[1]全等元素测试grid [[2,2],[2,2]] # 预期输出[2]明显菱形测试grid [ [1,2,3], [4,5,6], [7,8,9] ] # 中心菱形和为8524625如果边长为1多个菱形竞争测试grid [ [3,4,5,1,3], [3,3,4,2,3], [2,4,4,2,4], [2,4,5,3,1], [3,1,3,4,1] ] # 应能正确识别前三大菱形和边界情况测试grid [ [1,1,1], [1,1,1], [1,1,1] ] # 所有可能的菱形和都相同9. 算法扩展与变种这个问题可以延伸出几个有趣的变种最大单个菱形和只需找最大的一个菱形和可以用类似方法但只需维护一个最大值。菱形内部和计算菱形内部所有元素的和而不仅是边界。这时需要结合矩形前缀和与斜向前缀和。非正方形菱形放宽菱形定义允许长轴和短轴不同的菱形需要调整边界计算方式。动态更新查询在矩阵元素可以动态更新的情况下如何高效维护菱形和查询。这需要更高级的数据结构如二维线段树。三维菱形和将问题扩展到三维空间计算立方体中旋转45度的菱形体和。需要构建三维斜向前缀和。10. 实际应用场景虽然这个问题看起来是纯数学的但其核心思想在实际中有重要应用图像处理在边缘检测和特征提取中需要计算特定方向上的像素值变化。斜向前缀和可以加速对角线方向的特征计算。地理信息系统计算不规则区域如菱形辐射区内的统计量时类似的技术可以优化计算效率。游戏开发在战棋类游戏中计算角色技能的影响范围如菱形攻击范围和伤害值时需要快速求和相关区域。数据挖掘在分析二维数据分布时可能需要检测特定方向的异常模式斜向求和可以帮助快速定位。数值计算在求解偏微分方程时特定方向的差分计算可以转化为斜向区间求和问题。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询