news 2026/8/31 5:09:17

2026-08-30:矩阵中最大共享路径和。用go语言,有一个 m 行 n 列的整数矩阵。 第一个玩家从矩阵的左上角出发,只能向右或向下走,最终要走到右下角。 第二个玩家从左下角出发,只能向右或向上走

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
2026-08-30:矩阵中最大共享路径和。用go语言,有一个 m 行 n 列的整数矩阵。 第一个玩家从矩阵的左上角出发,只能向右或向下走,最终要走到右下角。 第二个玩家从左下角出发,只能向右或向上走

2026-08-30:矩阵中最大共享路径和。用go语言,有一个 m 行 n 列的整数矩阵。

第一个玩家从矩阵的左上角出发,只能向右或向下走,最终要走到右下角。

第二个玩家从左下角出发,只能向右或向上走,最终要走到右上角。

每个玩家各自选一条符合自己移动规则的完整路线。

如果某个格子同时被这两个玩家选中的路线经过,就称它为“共享格子”。

现在请你计算:在所有可能的路线组合中,所有共享格子上的数值之和,最大可以达到多少。

最后返回这个最大总和值。

m == grid.length。

n == grid[i].length。

2 <= m, n <= 1000。

4 <= m * n <= 500000。

-100 <= grid[i][j] <= 100。

输入: grid = [[1,2,0,-3],[1,-2,1,0],[-4,2,-1,3],[3,-3,3,-2],[-1,-5,0,1]]。

输出: 4。

解释:

图中展示了一种最优路径选择。

玩家 1 沿着从左上角到右下角的红色/紫色路径移动:

(0, 0) → (1, 0) → (2, 0) → (2, 1) → (2, 2) → (2, 3) → (3, 3) → (4, 3)

玩家 2 沿着从左下角到右上角的蓝色/紫色路径移动:

(4, 0) → (4, 1) → (3, 1) → (2, 1) → (2, 2) → (2, 3) → (1, 3) → (0, 3)

共享单元格为 (2, 1) 、(2, 2) 和 (2, 3) 。

总和为 2 + (-1) + 3 = 4 ,这是可能的最大总和。

题目来自力扣3938。

一、题目核心理解

  • 两个玩家路径形状不同:
    • 玩家1:左上 → 右下,只能右/下
    • 玩家2:左下 → 右上,只能右/上
  • 两条路径共享的格子,它们的值会被加总。
  • 我们要找所有可能路径组合中,共享格子值之和的最大值

二、算法整体思路(根据代码推导)

代码并没有直接模拟两条路径,而是将问题转化为“寻找矩阵中某个方向上的最大子数组和”,这一点需要先说明:

关键观察(隐含的数学性质)

对于这种“一个从左上到右下,一个从左下到右上”的路径,它们共享的格子一定形成一条连续的水平或垂直段(因为移动方向限制)。
具体地,在这个 4 方向限制下,两条路径的交集要么是一条水平连续段,要么是一条垂直连续段(也可能只是一个点,但单点可视为长度为1的段)。

因此:

  • 如果共享段是水平的,那么它就是某一行中连续的一段。
  • 如果共享段是垂直的,那么它就是某一列中连续的一段。

于是问题变成:

在矩阵中,找出所有可能作为共享段的水平连续段垂直连续段,计算它们的和,取最大值。


三、代码对应步骤分解

1. 定义辅助函数maxSubArray(nums)
  • 功能:计算一个数组中长度至少为 2的连续子数组的最大和。
  • 实现方式:
    • 用动态规划,f表示以当前元素结尾的最大子数组和(允许长度为1)
    • 但是,为了强制长度 ≥ 2,它每次用f + x来更新答案,这保证至少有两个数。
    • 再更新f = max(f, 0) + x,相当于允许从当前元素重新开始(但用于后续组合)。
2. 主函数maxScore(grid)处理过程

步骤 2.1 – 初始化

  • 获取行数m、列数n
  • 答案ans初始为极小值(负无穷)。

步骤 2.2 – 处理长度为 1 的共享段(单格子)

  • 条件:m > 2 && n > 2,即矩阵内部有非边界格子。
  • 遍历所有不在最外圈的格子(行 1 到 m-2,列 1 到 n-2)。
  • 对于这些格子,单独取它的值(作为长度为1的共享段),更新ans
  • 为什么只取内部?因为边界格子不可能成为两条路径的唯一共享点(路径起始或终点本身虽可共享,但题目隐含最大和不会只取边界单点,且代码特意排除)。

步骤 2.3 – 处理水平共享段(长度 ≥ 2)

  • 遍历每一行。
  • 对每一行,调用maxSubArray计算该行中长度 ≥ 2 的最大连续子数组和。
  • 更新ans

步骤 2.4 – 处理垂直共享段(长度 ≥ 2)

  • 对每一列:
    • 提取该列所有元素,组成一个长度为m的临时数组col
    • 对该数组调用maxSubArray,得到该列中长度 ≥ 2 的最大连续子数组和。
    • 更新ans

步骤 2.5 – 返回答案

  • 返回最终ans

四、关于为什么这样能覆盖所有情况(简要解释)

  • 两条路径的交集,由于移动方向限制,确实只会是一条水平或垂直的连续段
  • 段的长度可以是 1 或多个格子。
  • 代码分别覆盖了:
    • 长度为1(仅内部格子)
    • 长度≥2(按行或按列求最大子数组和)
  • 因此,它能找到所有可能的共享段的最大和。

五、时间复杂度和空间复杂度

时间复杂度
  • 行扫描:对每一行调用maxSubArray,每行长度 n,共 m 行 →O(m·n)
  • 列扫描:对每一列,构造长度为 m 的数组,共 n 列 →O(n·m)
  • 单格子扫描:最多 (m-2)·(n-2) 个 → 也是O(m·n)
  • 总体:O(m·n)
额外空间复杂度
  • 仅用了一个长度为m的临时数组col用于提取列。
  • 其余为常数变量。
  • 因此额外空间为O(m)(因为列长度最大为 m)。

六、总结

  • 算法本质:将二维路径共享问题,降维成一维最大子数组问题
  • 分三类情况处理共享段:单点、水平段、垂直段。
  • 时间复杂度O(m·n),空间复杂度O(m)(或 O(min(m,n)),这里取 O(m))。

如果你还想进一步了解为什么两条路径的交集一定只是水平或垂直连续段,我可以画图或给出更直观的证明。

Go完整代码如下:

packagemainimport("fmt""math""slices")funcmaxSubArray(nums[]int)int{ans:=math.MinInt// 注意答案可以是负数,不能初始化成 0f:=nums[0]for_,x:=rangenums[1:]{ans=max(ans,f+x)// f+x 保证子数组至少有两个数f=max(f,0)+x}returnans}funcmaxScore(grid[][]int)int{m,n:=len(grid),len(grid[0])ans:=math.MinInt// 单独计算子数组长为 1 的情况,此时子数组不能在 grid 的边界上ifm>2&&n>2{for_,row:=rangegrid[1:m-1]{ans=max(ans,slices.Max(row[1:n-1]))}}// 每行的最大子数组和(子数组长度 >= 2)for_,row:=rangegrid{ans=max(ans,maxSubArray(row))}// 每列的最大子数组和(子数组长度 >= 2)col:=make([]int,m)forj:=rangen{fori,row:=rangegrid{col[i]=row[j]}ans=max(ans,maxSubArray(col))}returnans}funcmain(){grid:=[][]int{{1,2,0,-3},{1,-2,1,0},{-4,2,-1,3},{3,-3,3,-2},{-1,-5,0,1}}result:=maxScore(grid)fmt.Println(result)}

Python完整代码如下:

# -*-coding:utf-8-*-importmathfromtypingimportListdefmax_sub_array(nums:List[int])->int:# 注意答案可以是负数,不能初始化成 0ans=-math.inf f=nums[0]forxinnums[1:]:# f+x 保证子数组至少有两个数ans=max(ans,f+x)f=max(f,0)+xreturnansdefmax_score(grid:List[List[int]])->int:m,n=len(grid),len(grid[0])ans=-math.inf# 单独计算子数组长为 1 的情况,此时子数组不能在 grid 的边界上ifm>2andn>2:forrowingrid[1:m-1]:# 注意切片是左闭右开,row[1:n-1] 会排除第一列和最后一列ifrow[1:n-1]:ans=max(ans,max(row[1:n-1]))# 每行的最大子数组和(子数组长度 >= 2)forrowingrid:ans=max(ans,max_sub_array(row))# 每列的最大子数组和(子数组长度 >= 2)forjinrange(n):col=[grid[i][j]foriinrange(m)]ans=max(ans,max_sub_array(col))returnansif__name__=="__main__":grid=[[1,2,0,-3],[1,-2,1,0],[-4,2,-1,3],[3,-3,3,-2],[-1,-5,0,1]]result=max_score(grid)print(result)

C++完整代码如下:

#include<iostream>#include<vector>#include<algorithm>#include<climits>usingnamespacestd;intmaxSubArray(constvector<int>&nums){// 注意答案可以是负数,不能初始化成 0intans=INT_MIN;intf=nums[0];for(size_t i=1;i<nums.size();i++){intx=nums[i];// f+x 保证子数组至少有两个数ans=max(ans,f+x);f=max(f,0)+x;}returnans;}intmaxScore(constvector<vector<int>>&grid){intm=grid.size();intn=grid[0].size();intans=INT_MIN;// 单独计算子数组长为 1 的情况,此时子数组不能在 grid 的边界上if(m>2&&n>2){for(inti=1;i<m-1;i++){// 找到 row[1:n-1] 中的最大值intmaxVal=INT_MIN;for(intj=1;j<n-1;j++){maxVal=max(maxVal,grid[i][j]);}ans=max(ans,maxVal);}}// 每行的最大子数组和(子数组长度 >= 2)for(constauto&row:grid){ans=max(ans,maxSubArray(row));}// 每列的最大子数组和(子数组长度 >= 2)vector<int>col(m);for(intj=0;j<n;j++){for(inti=0;i<m;i++){col[i]=grid[i][j];}ans=max(ans,maxSubArray(col));}returnans;}intmain(){vector<vector<int>>grid={{1,2,0,-3},{1,-2,1,0},{-4,2,-1,3},{3,-3,3,-2},{-1,-5,0,1}};intresult=maxScore(grid);cout<<result<<endl;return0;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/31 5:07:49

后端技术面试全流程复盘:从项目深挖到系统设计实战

不少朋友私信问最近面试的情况&#xff0c;我就把今天这场完整复盘一下。这次面的是某互联网公司的后端开发岗&#xff0c;整体面下来节奏紧凑&#xff0c;一面技术、二面系统设计、三面HR&#xff0c;总共三轮连轴转。面完最大的感受是&#xff1a;现在面试越来越不看“背了多…

作者头像 李华
网站建设 2026/8/31 5:06:09

李宏毅2021机器学习深度学习课程:从笔记到实战的完整刷课指南

简介&#xff1a;本资源是李宏毅教授2021年春季《机器学习与深度学习》课程的配套学习材料合集&#xff0c;面向高校学生、AI初学者及自学者&#xff0c;系统支撑理论理解、代码实践与作业复现。压缩包共122个文件&#xff0c;涵盖40份PPT课件&#xff08;含Domain Adaptation、…

作者头像 李华
网站建设 2026/8/31 5:04:17

车辆横向控制中的MPC联合仿真:从CarSim到Simulink的完整实践

简介&#xff1a;本资源是一套完整的汽车路径跟踪控制系统设计与仿真方案&#xff0c;面向车辆工程、自动化及控制科学等专业的本科生课程设计、毕业设计与科研项目开发者&#xff0c;解决智能汽车在CarSim高精度车辆模型中实现MPC轨迹跟踪控制的核心问题。压缩包共9个文件&…

作者头像 李华
网站建设 2026/8/31 5:04:12

脑机单词速记为什么不是“买两台学习舱就能开课”?

直接回答&#xff1a;因为学习舱只是交付载体。机构真正要落地的是一套由入学测评、读准背熟、舱内训练、出舱检测、纸笔复现、按时复习和教师执行组成的课程产品。少了课程、标准、培训和记录&#xff0c;设备到了校区&#xff0c;也不等于具备稳定开课能力。 一、先分清“设…

作者头像 李华
网站建设 2026/8/31 5:03:37

农业病虫害知识图谱构建实战:从爬虫到Neo4j可视化

简介&#xff1a;本资源是一个面向农业信息化开发者与智能农业研究者的知识图谱应用系统&#xff0c;聚焦病虫害检测场景&#xff0c;提供从数据采集到语义查询的完整技术链路。系统基于D2R映射框架构建农业病虫害知识图谱&#xff0c;集成网页端查询界面与后端Java服务&#x…

作者头像 李华
网站建设 2026/8/31 5:03:18

公交POV拍摄全流程:从设备固定到站点标记,记录城市交通运行秩序

一条写有“南禅寺&#xff08;朝阳广场&#xff09;→团结路公交停车场”的62路公交POV&#xff0c;拍摄时长约45分钟&#xff0c;视频标题里还带着“落幕”的字样。放在几年前的视频平台上&#xff0c;这只是公交爱好者日常记录里的一条。但如果你把这类内容当作一次完整的城市…

作者头像 李华